summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Src/eclipse/.metadata/.log845
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/.log1
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/CatcherDriver.1330426096136.pdombin0 -> 5419008 bytes
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.cdt.make.core/CatcherDriver.sc228
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/36/a07dff68fd6100111a83ded3e22caa93823
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/c9/f0b573ecfa6100111a83ded3e22caa93824
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.indexbin151 -> 151 bytes
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/6.treebin0 -> 84968 bytes
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resourcesbin764 -> 768 bytes
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs4
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.history3
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.index2
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml7
-rw-r--r--Src/eclipse/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml6
-rw-r--r--Src/osmolib/include/l1ctl_proto.h3
-rw-r--r--Src/osmolib/src/.cproject209
-rw-r--r--Src/osmolib/src/.project77
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/calypso_pll/pll.pl0
-rwxr-xr-xSrc/osmolib/src/host/fb_tools/bdf_to_c.py294
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/gsmmap/git-version-gen0
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/common/Makefile.am2
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/common/logging.h2
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/common/networks.h2
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/common/osmocom_data.h2
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/common/sim.h10
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/Makefile.am5
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h33
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm480_ss.h9
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h7
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h13
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/mncc.h11
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/settings.h4
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/subscriber.h4
-rw-r--r--Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/transaction.h19
-rw-r--r--Src/osmolib/src/host/layer23/src/common/Makefile.am2
-rw-r--r--Src/osmolib/src/host/layer23/src/common/gps.c23
-rw-r--r--Src/osmolib/src/host/layer23/src/common/l1ctl.c2
-rw-r--r--Src/osmolib/src/host/layer23/src/common/l1ctl_lapdm_glue.c2
-rw-r--r--Src/osmolib/src/host/layer23/src/common/l1l2_interface.c3
-rw-r--r--Src/osmolib/src/host/layer23/src/common/logging.c11
-rw-r--r--Src/osmolib/src/host/layer23/src/common/main.c1
-rw-r--r--Src/osmolib/src/host/layer23/src/common/networks.c2
-rw-r--r--Src/osmolib/src/host/layer23/src/common/sap_interface.c3
-rw-r--r--Src/osmolib/src/host/layer23/src/common/sim.c21
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/app_bcch_scan.c1
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/app_cbch_sniff.c1
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/app_ccch_scan.c34
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/app_echo_test.c1
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/bcch_scan.c3
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/layer23/src/misc/catcherbin951882 -> 1003279 bytes
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/catcher.c13
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/cell_log.c1
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/rslms.c2
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/Makefile.am4
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/app_mobile.c9
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/gsm322.c12
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/gsm411_sms.c941
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/gsm480_ss.c1289
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/gsm48_cc.c41
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/gsm48_mm.c293
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/gsm48_rr.c590
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/main.c47
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/mnccms.c4
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/settings.c5
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/subscriber.c73
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/support.c2
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/transaction.c10
-rw-r--r--Src/osmolib/src/host/layer23/src/mobile/vty_interface.c148
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/osmocon/git-version-gen0
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/osmocon/memdump_convert.pl0
-rw-r--r--Src/osmolib/src/host/osmocon/osmocon.c10
-rw-r--r--Src/osmolib/src/host/osmocon/osmoload.c4
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/rita_pll/mtk_pll.pl0
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/host/rita_pll/rita_pll.pl0
-rw-r--r--Src/osmolib/src/shared/libosmocore/.gitignore26
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc16gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc32gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc64gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc8gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/src/crc16gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/src/crc32gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/src/crc64gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/src/crc8gen.c120
-rwxr-xr-xSrc/osmolib/src/shared/libosmocore/build-host/tests/a5/a5_test225
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-host/tests/atconfig20
-rwxr-xr-xSrc/osmolib/src/shared/libosmocore/build-host/tests/auth/milenage_test225
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/shared/libosmocore/build-host/tests/bits/bitrev_test2
-rwxr-xr-xSrc/osmolib/src/shared/libosmocore/build-host/tests/conv/conv_test225
-rwxr-xr-xSrc/osmolib/src/shared/libosmocore/build-host/tests/gsm0808/gsm0808_test225
-rwxr-xr-xSrc/osmolib/src/shared/libosmocore/build-host/tests/lapd/lapd_test225
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-arfcn2
-rwxr-xr-xSrc/osmolib/src/shared/libosmocore/build-host/utils/osmo-auc-gen225
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc16gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc32gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc64gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc8gen.h59
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/src/crc16gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/src/crc32gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/src/crc64gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/src/crc8gen.c120
-rw-r--r--Src/osmolib/src/shared/libosmocore/build-target/tests/atconfig20
-rw-r--r--Src/osmolib/src/shared/libosmocore/configure.ac11
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/shared/libosmocore/debian/rules0
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/shared/libosmocore/git-version-gen0
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/Makefile.am11
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/conv.h67
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/crcXXgen.h.tpl59
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap.h62
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap_util.h9
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/linuxrbtree.h160
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/logging.h5
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/msgb.h26
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/prim.h3
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer.h6
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer_compat.h79
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/core/utils.h3
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/Makefile.am2
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/auth.h90
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/Makefile.am3
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/a5.h20
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/comp128.h2
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smc.h62
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smr.h45
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_utils.h36
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0808.h3
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm48_ie.h2
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapd_core.h171
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapdm.h60
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/Makefile.am2
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_08.h6
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_11.h8
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_44_318.h153
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/sysinfo.h2
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/tlv.h42
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/vty/telnet_interface.h2
-rw-r--r--Src/osmolib/src/shared/libosmocore/include/osmocom/vty/vty.h4
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/Makefile.am15
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/backtrace.c4
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/conv.c174
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/crcXXgen.c.tpl120
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/Makefile.am14
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/a5.c114
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/auth_comp128v1.c47
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/auth_core.c121
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/auth_milenage.c109
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/comp128.c2
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smc.c539
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smr.c451
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_utils.c306
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/gsm0808.c183
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/gsm48.c2
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/lapd_core.c2170
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/lapdm.c1991
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c38
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c121
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal.c805
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes.h27
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_i.h122
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h48
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/common.h20
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/crypto.h0
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/includes.h0
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.c329
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.h33
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/gsmtap_util.c49
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/logging.c12
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/logging_syslog.c2
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/rbtree.c383
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/serial.c24
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/socket.c2
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/timer.c178
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/utils.c6
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/vty/logging_vty.c25
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/vty/telnet_interface.c12
-rw-r--r--Src/osmolib/src/shared/libosmocore/src/vty/vty.c8
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/Makefile.am43
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/a5/Makefile.am6
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.c98
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.ok6
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/auth/Makefile.am8
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.c78
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.ok8
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/bits/Makefile.am1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/bits/bitrev_test.ok24
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/conv/Makefile.am6
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.c486
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.ok55
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/gsm0808/Makefile.am6
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.c269
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.ok15
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/lapd/Makefile.am9
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.c319
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.ok20
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/msgfile/Makefile.am1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/msgfile/msgfile_test.ok1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/sms/Makefile.am1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/sms/sms_test.ok2
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/smscb/Makefile.am1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/smscb/smscb_test.ok4
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/testsuite.at73
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/timer/Makefile.am1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.c182
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.ok2
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/ussd/Makefile.am1
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.c6
-rw-r--r--Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.ok53
-rw-r--r--Src/osmolib/src/shared/libosmocore/utils/Makefile.am5
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/shared/libosmocore/utils/gen_website_doc_tree.sh0
-rw-r--r--Src/osmolib/src/shared/libosmocore/utils/osmo-auc-gen.c183
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/shared/update-libosmocore.sh0
-rw-r--r--Src/osmolib/src/target/firmware/Makefile28
-rw-r--r--Src/osmolib/src/target/firmware/abb/twl3025.c19
-rw-r--r--Src/osmolib/src/target/firmware/apps/chainload/main.c1
-rw-r--r--Src/osmolib/src/target/firmware/apps/compal_dsp_dump/main.c25
-rw-r--r--Src/osmolib/src/target/firmware/apps/hello_world/main.c41
-rw-r--r--Src/osmolib/src/target/firmware/apps/layer1/main.c48
-rw-r--r--Src/osmolib/src/target/firmware/apps/loader/main.c1
-rw-r--r--Src/osmolib/src/target/firmware/apps/rssi/main.c1544
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/target/firmware/apps/simtest/main.c75
-rw-r--r--Src/osmolib/src/target/firmware/board/compal/highram.lds4
-rw-r--r--Src/osmolib/src/target/firmware/board/compal/ram.lds4
-rw-r--r--Src/osmolib/src/target/firmware/board/compal_e86/init.c7
-rw-r--r--Src/osmolib/src/target/firmware/board/compal_e88/init.c6
-rw-r--r--Src/osmolib/src/target/firmware/board/compal_e99/init.c8
-rw-r--r--Src/osmolib/src/target/firmware/board/gta0x/init.c3
-rw-r--r--Src/osmolib/src/target/firmware/board/pirelli_dpl10/init.c42
-rw-r--r--Src/osmolib/src/target/firmware/board/se_j100/init.c7
-rw-r--r--Src/osmolib/src/target/firmware/calypso/backlight.c2
-rw-r--r--Src/osmolib/src/target/firmware/calypso/i2c.c6
-rw-r--r--Src/osmolib/src/target/firmware/calypso/keypad.c17
-rw-r--r--Src/osmolib/src/target/firmware/calypso/rtc.c5
-rw-r--r--Src/osmolib/src/target/firmware/calypso/sim.c717
-rw-r--r--Src/osmolib/src/target/firmware/comm/msgb.c1
-rw-r--r--Src/osmolib/src/target/firmware/comm/timer.c30
-rw-r--r--Src/osmolib/src/target/firmware/fb/4x6.c731
-rw-r--r--Src/osmolib/src/target/firmware/fb/5x8.c802
-rw-r--r--Src/osmolib/src/target/firmware/fb/c64.c1069
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_bw8.c311
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_dummy.c70
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_rgb332.c305
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_s6b33b1x.c193
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_ssd1783.c204
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_ssd1963.c196
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_st7558.c132
-rw-r--r--Src/osmolib/src/target/firmware/fb/fb_td014.c150
-rw-r--r--Src/osmolib/src/target/firmware/fb/font.c57
-rw-r--r--Src/osmolib/src/target/firmware/fb/framebuffer.c28
-rw-r--r--Src/osmolib/src/target/firmware/fb/helvB08.c833
-rw-r--r--Src/osmolib/src/target/firmware/fb/helvB14.c1195
-rw-r--r--Src/osmolib/src/target/firmware/fb/helvB24.c1871
-rw-r--r--Src/osmolib/src/target/firmware/fb/helvR08.c826
-rw-r--r--Src/osmolib/src/target/firmware/fb/helvR14.c1198
-rw-r--r--Src/osmolib/src/target/firmware/fb/helvR24.c1870
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/target/firmware/include/calypso/sim.h22
-rw-r--r--Src/osmolib/src/target/firmware/include/comm/timer.h23
-rw-r--r--Src/osmolib/src/target/firmware/include/fb/fb_bw8.h51
-rw-r--r--Src/osmolib/src/target/firmware/include/fb/fb_rgb332.h47
-rw-r--r--Src/osmolib/src/target/firmware/include/fb/font.h81
-rw-r--r--Src/osmolib/src/target/firmware/include/fb/framebuffer.h128
-rw-r--r--Src/osmolib/src/target/firmware/include/layer1/async.h3
-rw-r--r--Src/osmolib/src/target/firmware/include/layer1/l23_api.h3
-rw-r--r--Src/osmolib/src/target/firmware/include/layer1/sync.h1
-rw-r--r--Src/osmolib/src/target/firmware/include/rf/trf6151.h4
-rw-r--r--Src/osmolib/src/target/firmware/layer1/l23_api.c69
-rw-r--r--Src/osmolib/src/target/firmware/layer1/mframe_sched.c6
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_fbsb.c2
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_freq.c1
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_pm.c9
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_rach.c3
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_rx_nb.c2
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_tch.c4
-rw-r--r--Src/osmolib/src/target/firmware/layer1/prim_tx_nb.c2
-rw-r--r--Src/osmolib/src/target/firmware/layer1/tpu_window.c1
-rw-r--r--Src/osmolib/src/target/firmware/rf/mt6139.c4
-rw-r--r--Src/osmolib/src/target/firmware/rf/trf6151.c12
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/target_dsp/calypso/bin2cfile.py0
-rwxr-xr-x[-rw-r--r--]Src/osmolib/src/target_dsp/calypso/dump2coff.py0
-rw-r--r--Tex/Content/GSM.tex6
-rw-r--r--Tex/Images/icons/100baset hub.jpgbin0 -> 13191 bytes
-rw-r--r--Tex/Images/icons/10700.jpgbin0 -> 21967 bytes
-rw-r--r--Tex/Images/icons/10GE_FCoE.jpgbin0 -> 62702 bytes
-rw-r--r--Tex/Images/icons/15200.jpgbin0 -> 20238 bytes
-rw-r--r--Tex/Images/icons/3174 cluster contoller .jpgbin0 -> 12434 bytes
-rw-r--r--Tex/Images/icons/3200 mobile access router.jpgbin0 -> 20455 bytes
-rw-r--r--Tex/Images/icons/3x74 cluster controller.jpgbin0 -> 19882 bytes
-rw-r--r--Tex/Images/icons/6700.jpgbin0 -> 24101 bytes
-rw-r--r--Tex/Images/icons/7500ars(7513).jpgbin0 -> 29379 bytes
-rw-r--r--Tex/Images/icons/ACS.jpgbin0 -> 61180 bytes
-rw-r--r--Tex/Images/icons/ASR 1000 Series.jpgbin0 -> 33853 bytes
-rw-r--r--Tex/Images/icons/AXP.jpgbin0 -> 27161 bytes
-rw-r--r--Tex/Images/icons/CUBE.jpgbin0 -> 61349 bytes
-rw-r--r--Tex/Images/icons/Cisco telepresence manager.jpgbin0 -> 53444 bytes
-rw-r--r--Tex/Images/icons/Clock.jpgbin0 -> 23821 bytes
-rw-r--r--Tex/Images/icons/Content Acquirer.jpgbin0 -> 19988 bytes
-rw-r--r--Tex/Images/icons/Ground terminal.jpgbin0 -> 72635 bytes
-rw-r--r--Tex/Images/icons/MSE.jpgbin0 -> 62426 bytes
-rw-r--r--Tex/Images/icons/MXE.jpgbin0 -> 66957 bytes
-rw-r--r--Tex/Images/icons/Mediator.jpgbin0 -> 67567 bytes
-rw-r--r--Tex/Images/icons/NCE router.jpgbin0 -> 63122 bytes
-rw-r--r--Tex/Images/icons/NCE.jpgbin0 -> 60650 bytes
-rw-r--r--Tex/Images/icons/Network security.jpgbin0 -> 14113 bytes
-rw-r--r--Tex/Images/icons/Nexus 1000.jpgbin0 -> 61923 bytes
-rw-r--r--Tex/Images/icons/Nexus 2000.jpgbin0 -> 65074 bytes
-rw-r--r--Tex/Images/icons/Nexus 5000.jpgbin0 -> 60547 bytes
-rw-r--r--Tex/Images/icons/Nexus 7000.jpgbin0 -> 65346 bytes
-rw-r--r--Tex/Images/icons/RF modem.jpgbin0 -> 52286 bytes
-rw-r--r--Tex/Images/icons/Service Module.jpgbin0 -> 59518 bytes
-rw-r--r--Tex/Images/icons/Service Router.jpgbin0 -> 24851 bytes
-rw-r--r--Tex/Images/icons/Services.jpgbin0 -> 56768 bytes
-rw-r--r--Tex/Images/icons/Set top box.jpgbin0 -> 52374 bytes
-rw-r--r--Tex/Images/icons/Space router.jpgbin0 -> 59236 bytes
-rw-r--r--Tex/Images/icons/TP MCU.jpgbin0 -> 64225 bytes
-rw-r--r--Tex/Images/icons/VSS.jpgbin0 -> 25920 bytes
-rw-r--r--Tex/Images/icons/accesspoint.jpgbin0 -> 16704 bytes
-rw-r--r--Tex/Images/icons/ace.jpgbin0 -> 18936 bytes
-rw-r--r--Tex/Images/icons/adm.jpgbin0 -> 18242 bytes
-rw-r--r--Tex/Images/icons/androgynous person.jpgbin0 -> 17134 bytes
-rw-r--r--Tex/Images/icons/antenna.jpgbin0 -> 20164 bytes
-rw-r--r--Tex/Images/icons/arrows for pointing.jpgbin0 -> 20041 bytes
-rw-r--r--Tex/Images/icons/arrows motion.jpgbin0 -> 18313 bytes
-rw-r--r--Tex/Images/icons/arrows-other.jpgbin0 -> 57092 bytes
-rw-r--r--Tex/Images/icons/asic processor.jpgbin0 -> 19593 bytes
-rw-r--r--Tex/Images/icons/ata.jpgbin0 -> 15628 bytes
-rw-r--r--Tex/Images/icons/atm 3800.jpgbin0 -> 19048 bytes
-rw-r--r--Tex/Images/icons/atm router.jpgbin0 -> 21808 bytes
-rw-r--r--Tex/Images/icons/atm switch.jpgbin0 -> 21608 bytes
-rw-r--r--Tex/Images/icons/atm tag sw rtr.jpgbin0 -> 22523 bytes
-rw-r--r--Tex/Images/icons/atmfast gb ethsw.jpgbin0 -> 24701 bytes
-rw-r--r--Tex/Images/icons/avs.jpgbin0 -> 17030 bytes
-rw-r--r--Tex/Images/icons/bbfw media.jpgbin0 -> 26120 bytes
-rw-r--r--Tex/Images/icons/bbfw.jpgbin0 -> 12800 bytes
-rw-r--r--Tex/Images/icons/bbs.jpgbin0 -> 16218 bytes
-rw-r--r--Tex/Images/icons/bbsm.jpgbin0 -> 16747 bytes
-rw-r--r--Tex/Images/icons/brackets.jpgbin0 -> 21756 bytes
-rw-r--r--Tex/Images/icons/branch office.jpgbin0 -> 19778 bytes
-rw-r--r--Tex/Images/icons/breakout box.jpgbin0 -> 17556 bytes
-rw-r--r--Tex/Images/icons/bridge.jpgbin0 -> 13628 bytes
-rw-r--r--Tex/Images/icons/broadband router d.jpgbin0 -> 24268 bytes
-rw-r--r--Tex/Images/icons/bts10200.jpgbin0 -> 20113 bytes
-rw-r--r--Tex/Images/icons/cable modem.jpgbin0 -> 14859 bytes
-rw-r--r--Tex/Images/icons/cache director.jpgbin0 -> 17571 bytes
-rw-r--r--Tex/Images/icons/callmanager.jpgbin0 -> 19562 bytes
-rw-r--r--Tex/Images/icons/car.jpgbin0 -> 14499 bytes
-rw-r--r--Tex/Images/icons/carrier routing system.jpgbin0 -> 27098 bytes
-rw-r--r--Tex/Images/icons/catalyst access gateway.jpgbin0 -> 20141 bytes
-rw-r--r--Tex/Images/icons/cddi-fddi.jpgbin0 -> 16678 bytes
-rw-r--r--Tex/Images/icons/cdm.jpgbin0 -> 21155 bytes
-rw-r--r--Tex/Images/icons/cellular phone.jpgbin0 -> 22074 bytes
-rw-r--r--Tex/Images/icons/centri firewall.jpgbin0 -> 19958 bytes
-rw-r--r--Tex/Images/icons/cisco 1000.jpgbin0 -> 16875 bytes
-rw-r--r--Tex/Images/icons/cisco asa 5500.jpgbin0 -> 23921 bytes
-rw-r--r--Tex/Images/icons/cisco file engine.jpgbin0 -> 19000 bytes
-rw-r--r--Tex/Images/icons/cisco hub.jpgbin0 -> 24343 bytes
-rw-r--r--Tex/Images/icons/cisco unified presence server.jpgbin0 -> 24314 bytes
-rw-r--r--Tex/Images/icons/cisco unityexpress.jpgbin0 -> 40311 bytes
-rw-r--r--Tex/Images/icons/ciscoca.jpgbin0 -> 21928 bytes
-rw-r--r--Tex/Images/icons/ciscosecurity.jpgbin0 -> 23472 bytes
-rw-r--r--Tex/Images/icons/ciscoworks workstn.jpgbin0 -> 21343 bytes
-rw-r--r--Tex/Images/icons/class 4_5 switch.jpgbin0 -> 15627 bytes
-rw-r--r--Tex/Images/icons/cloud.jpgbin0 -> 14858 bytes
-rw-r--r--Tex/Images/icons/comm server.jpgbin0 -> 20684 bytes
-rw-r--r--Tex/Images/icons/concentrator.jpgbin0 -> 17695 bytes
-rw-r--r--Tex/Images/icons/contact center.jpgbin0 -> 26538 bytes
-rw-r--r--Tex/Images/icons/content engine.jpgbin0 -> 17582 bytes
-rw-r--r--Tex/Images/icons/content switch 11000.jpgbin0 -> 22654 bytes
-rw-r--r--Tex/Images/icons/content switch module.jpgbin0 -> 23710 bytes
-rw-r--r--Tex/Images/icons/content switch.jpgbin0 -> 21983 bytes
-rw-r--r--Tex/Images/icons/contentservice router.jpgbin0 -> 21092 bytes
-rw-r--r--Tex/Images/icons/cs-mars.jpgbin0 -> 20684 bytes
-rw-r--r--Tex/Images/icons/csm-s.jpgbin0 -> 23891 bytes
-rw-r--r--Tex/Images/icons/csu dsu.jpgbin0 -> 16818 bytes
-rw-r--r--Tex/Images/icons/cte.jpgbin0 -> 18069 bytes
-rw-r--r--Tex/Images/icons/cuc.jpgbin0 -> 32656 bytes
-rw-r--r--Tex/Images/icons/detector.jpgbin0 -> 20702 bytes
-rw-r--r--Tex/Images/icons/director-class fibre channel director.jpgbin0 -> 21027 bytes
-rw-r--r--Tex/Images/icons/directory server.jpgbin0 -> 18874 bytes
-rw-r--r--Tex/Images/icons/disk subsystem.jpgbin0 -> 22901 bytes
-rw-r--r--Tex/Images/icons/diskette.jpgbin0 -> 16442 bytes
-rw-r--r--Tex/Images/icons/distributed director.jpgbin0 -> 21284 bytes
-rw-r--r--Tex/Images/icons/dot-dot.jpgbin0 -> 7392 bytes
-rw-r--r--Tex/Images/icons/dpt.jpgbin0 -> 19134 bytes
-rw-r--r--Tex/Images/icons/dslam.jpgbin0 -> 19177 bytes
-rw-r--r--Tex/Images/icons/dual mode ap.jpgbin0 -> 24327 bytes
-rw-r--r--Tex/Images/icons/dwdm filter.jpgbin0 -> 15757 bytes
-rw-r--r--Tex/Images/icons/end office .jpgbin0 -> 25832 bytes
-rw-r--r--Tex/Images/icons/fax.jpgbin0 -> 17564 bytes
-rw-r--r--Tex/Images/icons/fc storage.jpgbin0 -> 20020 bytes
-rw-r--r--Tex/Images/icons/fddi ring.jpgbin0 -> 15611 bytes
-rw-r--r--Tex/Images/icons/fibre channel fabric switch.jpgbin0 -> 23352 bytes
-rw-r--r--Tex/Images/icons/file cabinet.jpgbin0 -> 19498 bytes
-rw-r--r--Tex/Images/icons/file server.jpgbin0 -> 15995 bytes
-rw-r--r--Tex/Images/icons/firewall.jpgbin0 -> 16102 bytes
-rw-r--r--Tex/Images/icons/floppy disk.jpgbin0 -> 17703 bytes
-rw-r--r--Tex/Images/icons/front end processor.jpgbin0 -> 18800 bytes
-rw-r--r--Tex/Images/icons/fwsm.jpgbin0 -> 22417 bytes
-rw-r--r--Tex/Images/icons/gatekeeper.jpgbin0 -> 28462 bytes
-rw-r--r--Tex/Images/icons/general applicance.jpgbin0 -> 19611 bytes
-rw-r--r--Tex/Images/icons/general processor.jpgbin0 -> 19070 bytes
-rw-r--r--Tex/Images/icons/generic building.jpgbin0 -> 25643 bytes
-rw-r--r--Tex/Images/icons/generic gateway.jpgbin0 -> 25186 bytes
-rw-r--r--Tex/Images/icons/generic softswitch.jpgbin0 -> 14330 bytes
-rw-r--r--Tex/Images/icons/gigabit switch router.jpgbin0 -> 25927 bytes
-rw-r--r--Tex/Images/icons/government building.jpgbin0 -> 21289 bytes
-rw-r--r--Tex/Images/icons/guard.jpgbin0 -> 20499 bytes
-rw-r--r--Tex/Images/icons/h.323.jpgbin0 -> 20118 bytes
-rw-r--r--Tex/Images/icons/hand_cell.jpgbin0 -> 25373 bytes
-rw-r--r--Tex/Images/icons/handheld.jpgbin0 -> 14572 bytes
-rw-r--r--Tex/Images/icons/hootphone.jpgbin0 -> 18828 bytes
-rw-r--r--Tex/Images/icons/host (generic).jpgbin0 -> 15819 bytes
-rw-r--r--Tex/Images/icons/host.jpgbin0 -> 11359 bytes
-rw-r--r--Tex/Images/icons/hp mini.jpgbin0 -> 17816 bytes
-rw-r--r--Tex/Images/icons/hub.jpgbin0 -> 18163 bytes
-rw-r--r--Tex/Images/icons/iad router.jpgbin0 -> 21610 bytes
-rw-r--r--Tex/Images/icons/ibm maniframe.jpgbin0 -> 15701 bytes
-rw-r--r--Tex/Images/icons/ibm mini (as400).jpgbin0 -> 14561 bytes
-rw-r--r--Tex/Images/icons/ibm tower.jpgbin0 -> 18497 bytes
-rw-r--r--Tex/Images/icons/icm.jpgbin0 -> 20969 bytes
-rw-r--r--Tex/Images/icons/ics.jpgbin0 -> 32226 bytes
-rw-r--r--Tex/Images/icons/intelliswitch stack.jpgbin0 -> 31180 bytes
-rw-r--r--Tex/Images/icons/ios firewall.jpgbin0 -> 19983 bytes
-rw-r--r--Tex/Images/icons/ios slb.jpgbin0 -> 17836 bytes
-rw-r--r--Tex/Images/icons/ip communicator.jpgbin0 -> 21407 bytes
-rw-r--r--Tex/Images/icons/ip dsl.jpgbin0 -> 22521 bytes
-rw-r--r--Tex/Images/icons/ip phone.jpgbin0 -> 21138 bytes
-rw-r--r--Tex/Images/icons/ip telephony router.jpgbin0 -> 25051 bytes
-rw-r--r--Tex/Images/icons/ip.jpgbin0 -> 19363 bytes
-rw-r--r--Tex/Images/icons/iptc.jpgbin0 -> 19256 bytes
-rw-r--r--Tex/Images/icons/iptv broadcast server.jpgbin0 -> 17717 bytes
-rw-r--r--Tex/Images/icons/iptv content manager.jpgbin0 -> 15950 bytes
-rw-r--r--Tex/Images/icons/iscsi router.jpgbin0 -> 24085 bytes
-rw-r--r--Tex/Images/icons/isdn switch.jpgbin0 -> 17260 bytes
-rw-r--r--Tex/Images/icons/itp.jpgbin0 -> 25089 bytes
-rw-r--r--Tex/Images/icons/jbod.jpgbin0 -> 15917 bytes
-rw-r--r--Tex/Images/icons/key.jpgbin0 -> 13222 bytes
-rw-r--r--Tex/Images/icons/keys.jpgbin0 -> 24073 bytes
-rw-r--r--Tex/Images/icons/lan2lan.jpgbin0 -> 21110 bytes
-rw-r--r--Tex/Images/icons/laptop.jpgbin0 -> 21142 bytes
-rw-r--r--Tex/Images/icons/layer 2 remote switch.jpgbin0 -> 18356 bytes
-rw-r--r--Tex/Images/icons/layer 3 switch.jpgbin0 -> 21247 bytes
-rw-r--r--Tex/Images/icons/lightweight ap.jpgbin0 -> 22714 bytes
-rw-r--r--Tex/Images/icons/local director.jpgbin0 -> 16330 bytes
-rw-r--r--Tex/Images/icons/lock.jpgbin0 -> 17083 bytes
-rw-r--r--Tex/Images/icons/longreach cpe.jpgbin0 -> 19167 bytes
-rw-r--r--Tex/Images/icons/mac woman.jpgbin0 -> 22418 bytes
-rw-r--r--Tex/Images/icons/macintosh.jpgbin0 -> 20149 bytes
-rw-r--r--Tex/Images/icons/man woman.jpgbin0 -> 24200 bytes
-rw-r--r--Tex/Images/icons/mas gateway.jpgbin0 -> 21072 bytes
-rw-r--r--Tex/Images/icons/mau.jpgbin0 -> 11871 bytes
-rw-r--r--Tex/Images/icons/mcu.jpgbin0 -> 20095 bytes
-rw-r--r--Tex/Images/icons/mdu.jpgbin0 -> 20117 bytes
-rw-r--r--Tex/Images/icons/me1100.jpgbin0 -> 17571 bytes
-rw-r--r--Tex/Images/icons/meetingplace.jpgbin0 -> 17245 bytes
-rw-r--r--Tex/Images/icons/mesh ap.jpgbin0 -> 23173 bytes
-rw-r--r--Tex/Images/icons/metro1500.jpgbin0 -> 21822 bytes
-rw-r--r--Tex/Images/icons/mgx 8000 multiservice switch.jpgbin0 -> 25919 bytes
-rw-r--r--Tex/Images/icons/microphone.jpgbin0 -> 18628 bytes
-rw-r--r--Tex/Images/icons/microwebserver.jpgbin0 -> 19410 bytes
-rw-r--r--Tex/Images/icons/mini vax.jpgbin0 -> 14982 bytes
-rw-r--r--Tex/Images/icons/mobile access ip phone.jpgbin0 -> 25710 bytes
-rw-r--r--Tex/Images/icons/mobile access router.jpgbin0 -> 24087 bytes
-rw-r--r--Tex/Images/icons/modem.jpgbin0 -> 12658 bytes
-rw-r--r--Tex/Images/icons/moh server.jpgbin0 -> 18766 bytes
-rw-r--r--Tex/Images/icons/multi-fabric server switch.jpgbin0 -> 32442 bytes
-rw-r--r--Tex/Images/icons/multilayer remote switch.jpgbin0 -> 20010 bytes
-rw-r--r--Tex/Images/icons/multilayer switch.jpgbin0 -> 24944 bytes
-rw-r--r--Tex/Images/icons/multiswdevice.jpgbin0 -> 22462 bytes
-rw-r--r--Tex/Images/icons/mux.jpgbin0 -> 18312 bytes
-rw-r--r--Tex/Images/icons/nac appliance.jpgbin0 -> 23212 bytes
-rw-r--r--Tex/Images/icons/netflow router.jpgbin0 -> 21583 bytes
-rw-r--r--Tex/Images/icons/netranger.jpgbin0 -> 19680 bytes
-rw-r--r--Tex/Images/icons/netsonar.jpgbin0 -> 19896 bytes
-rw-r--r--Tex/Images/icons/network management.jpgbin0 -> 21867 bytes
-rw-r--r--Tex/Images/icons/octel.jpgbin0 -> 18820 bytes
-rw-r--r--Tex/Images/icons/ons15500.jpgbin0 -> 24820 bytes
-rw-r--r--Tex/Images/icons/optical amplifier.jpgbin0 -> 14594 bytes
-rw-r--r--Tex/Images/icons/optical services router.jpgbin0 -> 23830 bytes
-rw-r--r--Tex/Images/icons/optical transport.jpgbin0 -> 25223 bytes
-rw-r--r--Tex/Images/icons/pad x.28.jpgbin0 -> 18893 bytes
-rw-r--r--Tex/Images/icons/pad.jpgbin0 -> 12915 bytes
-rw-r--r--Tex/Images/icons/page icon.jpgbin0 -> 10625 bytes
-rw-r--r--Tex/Images/icons/pbx switch.jpgbin0 -> 16143 bytes
-rw-r--r--Tex/Images/icons/pbx.jpgbin0 -> 20327 bytes
-rw-r--r--Tex/Images/icons/pc adapter card.jpgbin0 -> 25482 bytes
-rw-r--r--Tex/Images/icons/pc man.jpgbin0 -> 26307 bytes
-rw-r--r--Tex/Images/icons/pc router card.jpgbin0 -> 23264 bytes
-rw-r--r--Tex/Images/icons/pc software.jpgbin0 -> 22194 bytes
-rw-r--r--Tex/Images/icons/pc.jpgbin0 -> 20445 bytes
-rw-r--r--Tex/Images/icons/pc_video.jpgbin0 -> 17179 bytes
-rw-r--r--Tex/Images/icons/pda.jpgbin0 -> 20505 bytes
-rw-r--r--Tex/Images/icons/phone fax.jpgbin0 -> 17916 bytes
-rw-r--r--Tex/Images/icons/phone.jpgbin0 -> 21875 bytes
-rw-r--r--Tex/Images/icons/pipe.jpgbin0 -> 10137 bytes
-rw-r--r--Tex/Images/icons/pix.jpgbin0 -> 15766 bytes
-rw-r--r--Tex/Images/icons/pmc.jpgbin0 -> 24248 bytes
-rw-r--r--Tex/Images/icons/printer.jpgbin0 -> 11273 bytes
-rw-r--r--Tex/Images/icons/programmable sw.jpgbin0 -> 24713 bytes
-rw-r--r--Tex/Images/icons/protocol translator.jpgbin0 -> 15203 bytes
-rw-r--r--Tex/Images/icons/pxf.jpgbin0 -> 22677 bytes
-rw-r--r--Tex/Images/icons/radio tower.jpgbin0 -> 19444 bytes
-rw-r--r--Tex/Images/icons/ratemux.jpgbin0 -> 21724 bytes
-rw-r--r--Tex/Images/icons/relational database.jpgbin0 -> 14094 bytes
-rw-r--r--Tex/Images/icons/repeater.jpgbin0 -> 14950 bytes
-rw-r--r--Tex/Images/icons/route switch processor.jpgbin0 -> 22859 bytes
-rw-r--r--Tex/Images/icons/router in bldg.jpgbin0 -> 27897 bytes
-rw-r--r--Tex/Images/icons/router w firewall.jpgbin0 -> 26577 bytes
-rw-r--r--Tex/Images/icons/router w silicon switch.jpgbin0 -> 20037 bytes
-rw-r--r--Tex/Images/icons/router.jpgbin0 -> 18216 bytes
-rw-r--r--Tex/Images/icons/rps.jpgbin0 -> 17755 bytes
-rw-r--r--Tex/Images/icons/running man.jpgbin0 -> 20292 bytes
-rw-r--r--Tex/Images/icons/satellite dish.jpgbin0 -> 18505 bytes
-rw-r--r--Tex/Images/icons/satellite.jpgbin0 -> 14187 bytes
-rw-r--r--Tex/Images/icons/sc2200 signalling controller.jpgbin0 -> 21387 bytes
-rw-r--r--Tex/Images/icons/sc2200_vsc3000host.jpgbin0 -> 18498 bytes
-rw-r--r--Tex/Images/icons/scanner.jpgbin0 -> 23293 bytes
-rw-r--r--Tex/Images/icons/server switch.jpgbin0 -> 29608 bytes
-rw-r--r--Tex/Images/icons/server w pc router.jpgbin0 -> 16685 bytes
-rw-r--r--Tex/Images/icons/service control.jpgbin0 -> 19208 bytes
-rw-r--r--Tex/Images/icons/sip proxy server.jpgbin0 -> 19148 bytes
-rw-r--r--Tex/Images/icons/sitting woman.jpgbin0 -> 22356 bytes
-rw-r--r--Tex/Images/icons/small business.jpgbin0 -> 15702 bytes
-rw-r--r--Tex/Images/icons/small hub.jpgbin0 -> 16357 bytes
-rw-r--r--Tex/Images/icons/softphone.jpgbin0 -> 23616 bytes
-rw-r--r--Tex/Images/icons/softswitch_pgw_mgc.jpgbin0 -> 19411 bytes
-rw-r--r--Tex/Images/icons/speaker.jpgbin0 -> 19039 bytes
-rw-r--r--Tex/Images/icons/ssc.jpgbin0 -> 22627 bytes
-rw-r--r--Tex/Images/icons/ssl terminator.jpgbin0 -> 21771 bytes
-rw-r--r--Tex/Images/icons/standard host.jpgbin0 -> 18498 bytes
-rw-r--r--Tex/Images/icons/standing man icon.jpgbin0 -> 12408 bytes
-rw-r--r--Tex/Images/icons/standing woman.jpgbin0 -> 12263 bytes
-rw-r--r--Tex/Images/icons/stb.jpgbin0 -> 13754 bytes
-rw-r--r--Tex/Images/icons/storage array.jpgbin0 -> 20502 bytes
-rw-r--r--Tex/Images/icons/storage router.jpgbin0 -> 31032 bytes
-rw-r--r--Tex/Images/icons/stp.jpgbin0 -> 20140 bytes
-rw-r--r--Tex/Images/icons/streamer.jpgbin0 -> 20149 bytes
-rw-r--r--Tex/Images/icons/sun workstation.jpgbin0 -> 18018 bytes
-rw-r--r--Tex/Images/icons/supercomputer.jpgbin0 -> 23590 bytes
-rw-r--r--Tex/Images/icons/svx.jpgbin0 -> 25832 bytes
-rw-r--r--Tex/Images/icons/sw-based server.jpgbin0 -> 20916 bytes
-rw-r--r--Tex/Images/icons/system controller.jpgbin0 -> 21019 bytes
-rw-r--r--Tex/Images/icons/tablet.jpgbin0 -> 18805 bytes
-rw-r--r--Tex/Images/icons/tape array.jpgbin0 -> 19681 bytes
-rw-r--r--Tex/Images/icons/tdm router.jpgbin0 -> 21627 bytes
-rw-r--r--Tex/Images/icons/telecommuter house rtr.jpgbin0 -> 23536 bytes
-rw-r--r--Tex/Images/icons/telecommuter house.jpgbin0 -> 24671 bytes
-rw-r--r--Tex/Images/icons/telecomuter icon.jpgbin0 -> 18444 bytes
-rw-r--r--Tex/Images/icons/telephone poles.jpgbin0 -> 20935 bytes
-rw-r--r--Tex/Images/icons/terminal.jpgbin0 -> 19269 bytes
-rw-r--r--Tex/Images/icons/token ring.jpgbin0 -> 23674 bytes
-rw-r--r--Tex/Images/icons/transpath.jpgbin0 -> 23567 bytes
-rw-r--r--Tex/Images/icons/truck.jpgbin0 -> 14795 bytes
-rw-r--r--Tex/Images/icons/turret.jpgbin0 -> 21710 bytes
-rw-r--r--Tex/Images/icons/tv.jpgbin0 -> 27141 bytes
-rw-r--r--Tex/Images/icons/ubr910.jpgbin0 -> 15297 bytes
-rw-r--r--Tex/Images/icons/umg series.jpgbin0 -> 24073 bytes
-rw-r--r--Tex/Images/icons/unity server.jpgbin0 -> 20328 bytes
-rw-r--r--Tex/Images/icons/university.jpgbin0 -> 21782 bytes
-rw-r--r--Tex/Images/icons/unversal gateway.jpgbin0 -> 22702 bytes
-rw-r--r--Tex/Images/icons/upc.jpgbin0 -> 26154 bytes
-rw-r--r--Tex/Images/icons/ups.jpgbin0 -> 17533 bytes
-rw-r--r--Tex/Images/icons/vault.jpgbin0 -> 18826 bytes
-rw-r--r--Tex/Images/icons/video camera.jpgbin0 -> 16076 bytes
-rw-r--r--Tex/Images/icons/vip.jpgbin0 -> 21994 bytes
-rw-r--r--Tex/Images/icons/virtual layer switch.jpgbin0 -> 27030 bytes
-rw-r--r--Tex/Images/icons/voice atm switch.jpgbin0 -> 22193 bytes
-rw-r--r--Tex/Images/icons/voice gateway.jpgbin0 -> 23062 bytes
-rw-r--r--Tex/Images/icons/voice router.jpgbin0 -> 20788 bytes
-rw-r--r--Tex/Images/icons/voice switch.jpgbin0 -> 17226 bytes
-rw-r--r--Tex/Images/icons/vpn concentrator.jpgbin0 -> 24655 bytes
-rw-r--r--Tex/Images/icons/vpn gateway.jpgbin0 -> 15581 bytes
-rw-r--r--Tex/Images/icons/vsc 3000 virtual switch contrlr.jpgbin0 -> 19452 bytes
-rw-r--r--Tex/Images/icons/wae.jpgbin0 -> 18450 bytes
-rw-r--r--Tex/Images/icons/wavelength router.jpgbin0 -> 18341 bytes
-rw-r--r--Tex/Images/icons/web browser.jpgbin0 -> 21607 bytes
-rw-r--r--Tex/Images/icons/web cluster.jpgbin0 -> 27151 bytes
-rw-r--r--Tex/Images/icons/wi-fi tag.jpgbin0 -> 29777 bytes
-rw-r--r--Tex/Images/icons/wireless bridge.jpgbin0 -> 20432 bytes
-rw-r--r--Tex/Images/icons/wireless location appliance.jpgbin0 -> 16968 bytes
-rw-r--r--Tex/Images/icons/wireless router.jpgbin0 -> 21116 bytes
-rw-r--r--Tex/Images/icons/wireless transport.jpgbin0 -> 16714 bytes
-rw-r--r--Tex/Images/icons/wireless.jpgbin0 -> 14698 bytes
-rw-r--r--Tex/Images/icons/wism.jpgbin0 -> 26870 bytes
-rw-r--r--Tex/Images/icons/wlan controller.jpgbin0 -> 20850 bytes
-rw-r--r--Tex/Images/icons/workgroup director.jpgbin0 -> 22826 bytes
-rw-r--r--Tex/Images/icons/workgroup switch.jpgbin0 -> 15253 bytes
-rw-r--r--Tex/Images/icons/workstation.jpgbin0 -> 20700 bytes
-rw-r--r--Tex/Images/icons/www server.jpgbin0 -> 25159 bytes
-rw-r--r--Tex/Images/template.graphml39
-rw-r--r--Tex/Images/template.pngbin0 -> 1996 bytes
-rw-r--r--Tex/Master/Master.acn904
-rw-r--r--Tex/Master/Master.aux5
-rw-r--r--Tex/Master/Master.log1446
-rw-r--r--Tex/Master/Master.pdfbin4253860 -> 6427011 bytes
-rw-r--r--Tex/Master/Master.synctex.gzbin0 -> 309386 bytes
-rw-r--r--Tex/Master/Master.tex4
-rw-r--r--Tex/Master/Master.toc4
-rw-r--r--Tex/Master/titlepage.sty402
596 files changed, 35507 insertions, 4167 deletions
diff --git a/Src/eclipse/.metadata/.log b/Src/eclipse/.metadata/.log
index fade1c1..5890662 100644
--- a/Src/eclipse/.metadata/.log
+++ b/Src/eclipse/.metadata/.log
@@ -1803,3 +1803,848 @@ org.eclipse.core.runtime.AssertionFailedException: unknown saveable: org.eclipse
!ENTRY org.eclipse.cdt.core 1 0 2012-02-28 11:48:24.985
!MESSAGE Indexed 'CatcherDriver' (187 sources, 288 headers) in 8.65 sec: 27,880 declarations; 107,743 references; 8 unresolved inclusions; 10 syntax errors; 4,423 unresolved names (3.16%)
+!SESSION 2012-02-28 12:47:07.521 -----------------------------------------------
+eclipse.buildId=I20110613-1736
+java.version=1.6.0_23
+java.vendor=Sun Microsystems Inc.
+BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_US
+Command-line arguments: -os linux -ws gtk -arch x86_64
+
+!ENTRY org.eclipse.core.resources 4 567 2012-02-28 12:47:26.620
+!MESSAGE Workspace restored, but some problems occurred.
+!SUBENTRY 1 org.eclipse.core.resources 4 567 2012-02-28 12:47:26.620
+!MESSAGE Could not read metadata for 'CatcherDriver'.
+!STACK 1
+org.eclipse.core.internal.resources.ResourceException: The project description file (.project) for 'CatcherDriver' is missing. This file contains important information about the project. The project will not function properly until this file is restored.
+ at org.eclipse.core.internal.localstore.FileSystemResourceManager.read(FileSystemResourceManager.java:851)
+ at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:873)
+ at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:853)
+ at org.eclipse.core.internal.resources.SaveManager.restore(SaveManager.java:702)
+ at org.eclipse.core.internal.resources.SaveManager.startup(SaveManager.java:1527)
+ at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2503)
+ at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2251)
+ at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:439)
+ at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
+ at java.security.AccessController.doPrivileged(Native Method)
+ at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
+ at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
+ at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
+ at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
+ at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
+ at org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
+ at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
+ at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
+ at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
+ at org.eclipse.osgi.internal.loader.SingleSourcePackage.loadClass(SingleSourcePackage.java:35)
+ at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:473)
+ at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
+ at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
+ at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
+ at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+!SUBENTRY 2 org.eclipse.core.resources 4 567 2012-02-28 12:47:26.621
+!MESSAGE The project description file (.project) for 'CatcherDriver' is missing. This file contains important information about the project. The project will not function properly until this file is restored.
+
+!ENTRY org.eclipse.core.filebuffers 4 2 2012-02-28 12:47:28.712
+!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.core.filebuffers".
+!STACK 0
+java.lang.NullPointerException
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.createProjDescriptionForDescriptor(CConfigBasedDescriptorManager.java:374)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.findDescriptor(CConfigBasedDescriptorManager.java:341)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.getDescriptor(CConfigBasedDescriptorManager.java:238)
+ at org.eclipse.cdt.core.CCorePlugin.getCProjectDescription(CCorePlugin.java:640)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.load(ProjectMap.java:117)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.<init>(ProjectMap.java:58)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getProjectMap(DocCommentOwnerManager.java:212)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getCommentOwner(DocCommentOwnerManager.java:129)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.getDocumentationCommentOwner(CTextTools.java:157)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.setupCDocument(CTextTools.java:118)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant.setup(CDocumentSetupParticipant.java:48)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager$1.run(ResourceTextFileBufferManager.java:151)
+ at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager.createEmptyDocument(ResourceTextFileBufferManager.java:166)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBuffer.initializeFileBufferContent(ResourceTextFileBuffer.java:289)
+ at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:245)
+ at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:112)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:559)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.createFileInfo(CDocumentProvider.java:856)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:478)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.connect(CDocumentProvider.java:778)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4213)
+ at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:237)
+ at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1451)
+ at org.eclipse.ui.editors.text.TextEditor.doSetInput(TextEditor.java:169)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1380)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
+ at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1459)
+ at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:972)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
+ at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.core.filebuffers 4 0 2012-02-28 12:47:28.715
+!MESSAGE A document setup participant failed to setup the document.
+!STACK 0
+java.lang.NullPointerException
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.createProjDescriptionForDescriptor(CConfigBasedDescriptorManager.java:374)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.findDescriptor(CConfigBasedDescriptorManager.java:341)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.getDescriptor(CConfigBasedDescriptorManager.java:238)
+ at org.eclipse.cdt.core.CCorePlugin.getCProjectDescription(CCorePlugin.java:640)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.load(ProjectMap.java:117)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.<init>(ProjectMap.java:58)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getProjectMap(DocCommentOwnerManager.java:212)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getCommentOwner(DocCommentOwnerManager.java:129)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.getDocumentationCommentOwner(CTextTools.java:157)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.setupCDocument(CTextTools.java:118)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant.setup(CDocumentSetupParticipant.java:48)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager$1.run(ResourceTextFileBufferManager.java:151)
+ at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager.createEmptyDocument(ResourceTextFileBufferManager.java:166)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBuffer.initializeFileBufferContent(ResourceTextFileBuffer.java:289)
+ at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:245)
+ at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:112)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:559)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.createFileInfo(CDocumentProvider.java:856)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:478)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.connect(CDocumentProvider.java:778)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4213)
+ at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:237)
+ at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1451)
+ at org.eclipse.ui.editors.text.TextEditor.doSetInput(TextEditor.java:169)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1380)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
+ at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1459)
+ at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:972)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
+ at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.core.filebuffers 4 2 2012-02-28 12:47:28.716
+!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.core.filebuffers".
+!STACK 0
+java.lang.NullPointerException
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.createProjDescriptionForDescriptor(CConfigBasedDescriptorManager.java:374)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.findDescriptor(CConfigBasedDescriptorManager.java:341)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.getDescriptor(CConfigBasedDescriptorManager.java:238)
+ at org.eclipse.cdt.core.CCorePlugin.getCProjectDescription(CCorePlugin.java:640)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.load(ProjectMap.java:117)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.<init>(ProjectMap.java:58)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getProjectMap(DocCommentOwnerManager.java:212)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getCommentOwner(DocCommentOwnerManager.java:129)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.getDocumentationCommentOwner(CTextTools.java:157)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.setupCDocument(CTextTools.java:118)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant.setup(CDocumentSetupParticipant.java:48)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager$1.run(ResourceTextFileBufferManager.java:151)
+ at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager.createEmptyDocument(ResourceTextFileBufferManager.java:166)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBuffer.initializeFileBufferContent(ResourceTextFileBuffer.java:289)
+ at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:245)
+ at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:112)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:559)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.createFileInfo(CDocumentProvider.java:856)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:478)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.connect(CDocumentProvider.java:778)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4213)
+ at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:237)
+ at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1451)
+ at org.eclipse.ui.editors.text.TextEditor.doSetInput(TextEditor.java:169)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1380)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
+ at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1459)
+ at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:972)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
+ at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.core.filebuffers 4 0 2012-02-28 12:47:28.717
+!MESSAGE A document setup participant failed to setup the document.
+!STACK 0
+java.lang.NullPointerException
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.createProjDescriptionForDescriptor(CConfigBasedDescriptorManager.java:374)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.findDescriptor(CConfigBasedDescriptorManager.java:341)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.getDescriptor(CConfigBasedDescriptorManager.java:238)
+ at org.eclipse.cdt.core.CCorePlugin.getCProjectDescription(CCorePlugin.java:640)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.load(ProjectMap.java:117)
+ at org.eclipse.cdt.internal.ui.text.doctools.ProjectMap.<init>(ProjectMap.java:58)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getProjectMap(DocCommentOwnerManager.java:212)
+ at org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager.getCommentOwner(DocCommentOwnerManager.java:129)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.getDocumentationCommentOwner(CTextTools.java:157)
+ at org.eclipse.cdt.internal.ui.text.CTextTools.setupCDocument(CTextTools.java:118)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant.setup(CDocumentSetupParticipant.java:48)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager$1.run(ResourceTextFileBufferManager.java:151)
+ at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBufferManager.createEmptyDocument(ResourceTextFileBufferManager.java:166)
+ at org.eclipse.core.internal.filebuffers.ResourceTextFileBuffer.initializeFileBufferContent(ResourceTextFileBuffer.java:289)
+ at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:245)
+ at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:112)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:559)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.createFileInfo(CDocumentProvider.java:856)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:478)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.connect(CDocumentProvider.java:778)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4213)
+ at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:237)
+ at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1451)
+ at org.eclipse.ui.editors.text.TextEditor.doSetInput(TextEditor.java:169)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1380)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
+ at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1459)
+ at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:972)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
+ at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.ui 4 0 2012-02-28 12:47:28.766
+!MESSAGE Unable to create editor ID org.eclipse.cdt.ui.editor.CEditor: Editor could not be initialized.
+!STACK 0
+java.lang.NullPointerException
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.createProjDescriptionForDescriptor(CConfigBasedDescriptorManager.java:374)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.findDescriptor(CConfigBasedDescriptorManager.java:341)
+ at org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager.getDescriptor(CConfigBasedDescriptorManager.java:238)
+ at org.eclipse.cdt.core.CCorePlugin.getCProjectDescription(CCorePlugin.java:640)
+ at org.eclipse.cdt.internal.core.language.LanguageMappingStore.getProjectDescription(LanguageMappingStore.java:110)
+ at org.eclipse.cdt.internal.core.language.LanguageMappingStore.decodeMappings(LanguageMappingStore.java:75)
+ at org.eclipse.cdt.core.model.LanguageManager.getLanguageConfiguration(LanguageManager.java:447)
+ at org.eclipse.cdt.internal.core.language.LanguageMappingResolver.computeLanguage(LanguageMappingResolver.java:57)
+ at org.eclipse.cdt.core.model.LanguageManager.getLanguageForFile(LanguageManager.java:587)
+ at org.eclipse.cdt.internal.core.model.TranslationUnit.getLanguage(TranslationUnit.java:776)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1392)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
+ at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1459)
+ at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:972)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
+ at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.ui 2 2 2012-02-28 12:47:28.785
+!MESSAGE Ignored attempt to add saveable that was already registered
+!STACK 0
+org.eclipse.core.runtime.AssertionFailedException: unknown saveable: org.eclipse.ui.internal.DefaultSaveable@2c538cc2 from part: org.eclipse.ui.internal.ErrorEditorPart@2c538cc2
+ at org.eclipse.ui.internal.SaveablesList.logWarning(SaveablesList.java:187)
+ at org.eclipse.ui.internal.SaveablesList.addModel(SaveablesList.java:117)
+ at org.eclipse.ui.internal.SaveablesList.addModels(SaveablesList.java:289)
+ at org.eclipse.ui.internal.SaveablesList.postOpen(SaveablesList.java:695)
+ at org.eclipse.ui.internal.PartList.partOpened(PartList.java:234)
+ at org.eclipse.ui.internal.PartList.access$0(PartList.java:210)
+ at org.eclipse.ui.internal.PartList$1.propertyChanged(PartList.java:40)
+ at org.eclipse.ui.internal.WorkbenchPartReference.fireInternalPropertyChange(WorkbenchPartReference.java:375)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:610)
+ at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
+ at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1459)
+ at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:972)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
+ at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
+ at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
+ at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
+ at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
+ at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3563)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3212)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.ui 4 0 2012-02-28 12:47:36.715
+!MESSAGE Unable to create editor ID org.eclipse.cdt.ui.editor.CEditor: The file does not exist.
+!STACK 1
+org.eclipse.core.runtime.CoreException: The file does not exist.
+ at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:237)
+ at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:112)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:559)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.createFileInfo(CDocumentProvider.java:856)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:478)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.connect(CDocumentProvider.java:778)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4213)
+ at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:237)
+ at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1451)
+ at org.eclipse.ui.editors.text.TextEditor.doSetInput(TextEditor.java:169)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1380)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
+ at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
+ at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
+ at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
+ at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
+ at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1245)
+ at org.eclipse.ui.internal.PartStack.handleDeferredEvents(PartStack.java:1213)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.PartSashContainer.handleDeferredEvents(PartSashContainer.java:1409)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.WorkbenchPage.handleDeferredEvents(WorkbenchPage.java:1495)
+ at org.eclipse.ui.internal.WorkbenchPage.deferUpdates(WorkbenchPage.java:1485)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditors(WorkbenchPage.java:1459)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditor(WorkbenchPage.java:1523)
+ at org.eclipse.ui.internal.CloseEditorHandler.execute(CloseEditorHandler.java:47)
+ at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
+ at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
+ at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
+ at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123)
+ at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
+ at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1531)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1257)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1282)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1267)
+ at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1294)
+ at org.eclipse.swt.widgets.Widget.gtk_key_press_event(Widget.java:730)
+ at org.eclipse.swt.widgets.Control.gtk_key_press_event(Control.java:3019)
+ at org.eclipse.swt.widgets.Composite.gtk_key_press_event(Composite.java:734)
+ at org.eclipse.swt.widgets.Tree.gtk_key_press_event(Tree.java:2002)
+ at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1743)
+ at org.eclipse.swt.widgets.Control.windowProc(Control.java:5016)
+ at org.eclipse.swt.widgets.Tree.windowProc(Tree.java:3530)
+ at org.eclipse.swt.widgets.Display.windowProc(Display.java:4408)
+ at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8394)
+ at org.eclipse.swt.widgets.Display.eventProc(Display.java:1245)
+ at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2258)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207)
+ at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+!SUBENTRY 1 org.eclipse.core.filebuffers 4 0 2012-02-28 12:47:36.716
+!MESSAGE The file does not exist.
+
+!ENTRY org.eclipse.ui 2 2 2012-02-28 12:47:36.729
+!MESSAGE Ignored attempt to add saveable that was already registered
+!STACK 0
+org.eclipse.core.runtime.AssertionFailedException: unknown saveable: org.eclipse.ui.internal.DefaultSaveable@19166179 from part: org.eclipse.ui.internal.ErrorEditorPart@19166179
+ at org.eclipse.ui.internal.SaveablesList.logWarning(SaveablesList.java:187)
+ at org.eclipse.ui.internal.SaveablesList.addModel(SaveablesList.java:117)
+ at org.eclipse.ui.internal.SaveablesList.addModels(SaveablesList.java:289)
+ at org.eclipse.ui.internal.SaveablesList.postOpen(SaveablesList.java:695)
+ at org.eclipse.ui.internal.PartList.partOpened(PartList.java:234)
+ at org.eclipse.ui.internal.PartList.access$0(PartList.java:210)
+ at org.eclipse.ui.internal.PartList$1.propertyChanged(PartList.java:40)
+ at org.eclipse.ui.internal.WorkbenchPartReference.fireInternalPropertyChange(WorkbenchPartReference.java:375)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:610)
+ at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
+ at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
+ at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
+ at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
+ at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
+ at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1245)
+ at org.eclipse.ui.internal.PartStack.handleDeferredEvents(PartStack.java:1213)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.PartSashContainer.handleDeferredEvents(PartSashContainer.java:1409)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.WorkbenchPage.handleDeferredEvents(WorkbenchPage.java:1495)
+ at org.eclipse.ui.internal.WorkbenchPage.deferUpdates(WorkbenchPage.java:1485)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditors(WorkbenchPage.java:1459)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditor(WorkbenchPage.java:1523)
+ at org.eclipse.ui.internal.CloseEditorHandler.execute(CloseEditorHandler.java:47)
+ at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
+ at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
+ at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
+ at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123)
+ at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
+ at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1531)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1257)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1282)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1267)
+ at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1294)
+ at org.eclipse.swt.widgets.Widget.gtk_key_press_event(Widget.java:730)
+ at org.eclipse.swt.widgets.Control.gtk_key_press_event(Control.java:3019)
+ at org.eclipse.swt.widgets.Composite.gtk_key_press_event(Composite.java:734)
+ at org.eclipse.swt.widgets.Tree.gtk_key_press_event(Tree.java:2002)
+ at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1743)
+ at org.eclipse.swt.widgets.Control.windowProc(Control.java:5016)
+ at org.eclipse.swt.widgets.Tree.windowProc(Tree.java:3530)
+ at org.eclipse.swt.widgets.Display.windowProc(Display.java:4408)
+ at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8394)
+ at org.eclipse.swt.widgets.Display.eventProc(Display.java:1245)
+ at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2258)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207)
+ at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+
+!ENTRY org.eclipse.ui 4 0 2012-02-28 12:47:37.016
+!MESSAGE Unable to create editor ID org.eclipse.cdt.ui.editor.CEditor: The file does not exist.
+!STACK 1
+org.eclipse.core.runtime.CoreException: The file does not exist.
+ at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:237)
+ at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:112)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:559)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.createFileInfo(CDocumentProvider.java:856)
+ at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:478)
+ at org.eclipse.cdt.internal.ui.editor.CDocumentProvider.connect(CDocumentProvider.java:778)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4213)
+ at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:237)
+ at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1451)
+ at org.eclipse.ui.editors.text.TextEditor.doSetInput(TextEditor.java:169)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.internalDoSetInput(CEditor.java:1380)
+ at org.eclipse.cdt.internal.ui.editor.CEditor.doSetInput(CEditor.java:1345)
+ at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3200)
+ at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
+ at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
+ at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:759)
+ at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
+ at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:756)
+ at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2642)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3218)
+ at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3245)
+ at org.eclipse.ui.internal.EditorManager.createSite(EditorManager.java:828)
+ at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:647)
+ at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
+ at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
+ at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
+ at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
+ at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
+ at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
+ at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1245)
+ at org.eclipse.ui.internal.PartStack.handleDeferredEvents(PartStack.java:1213)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.PartSashContainer.handleDeferredEvents(PartSashContainer.java:1409)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.WorkbenchPage.handleDeferredEvents(WorkbenchPage.java:1495)
+ at org.eclipse.ui.internal.WorkbenchPage.deferUpdates(WorkbenchPage.java:1485)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditors(WorkbenchPage.java:1459)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditor(WorkbenchPage.java:1523)
+ at org.eclipse.ui.internal.CloseEditorHandler.execute(CloseEditorHandler.java:47)
+ at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
+ at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
+ at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
+ at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123)
+ at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
+ at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1531)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1257)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1282)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1267)
+ at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1294)
+ at org.eclipse.swt.widgets.Widget.gtk_key_press_event(Widget.java:730)
+ at org.eclipse.swt.widgets.Control.gtk_key_press_event(Control.java:3019)
+ at org.eclipse.swt.widgets.Composite.gtk_key_press_event(Composite.java:734)
+ at org.eclipse.swt.widgets.Tree.gtk_key_press_event(Tree.java:2002)
+ at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1743)
+ at org.eclipse.swt.widgets.Control.windowProc(Control.java:5016)
+ at org.eclipse.swt.widgets.Tree.windowProc(Tree.java:3530)
+ at org.eclipse.swt.widgets.Display.windowProc(Display.java:4408)
+ at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8394)
+ at org.eclipse.swt.widgets.Display.eventProc(Display.java:1245)
+ at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2258)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207)
+ at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
+!SUBENTRY 1 org.eclipse.core.filebuffers 4 0 2012-02-28 12:47:37.018
+!MESSAGE The file does not exist.
+
+!ENTRY org.eclipse.ui 2 2 2012-02-28 12:47:37.032
+!MESSAGE Ignored attempt to add saveable that was already registered
+!STACK 0
+org.eclipse.core.runtime.AssertionFailedException: unknown saveable: org.eclipse.ui.internal.DefaultSaveable@b53b098 from part: org.eclipse.ui.internal.ErrorEditorPart@b53b098
+ at org.eclipse.ui.internal.SaveablesList.logWarning(SaveablesList.java:187)
+ at org.eclipse.ui.internal.SaveablesList.addModel(SaveablesList.java:117)
+ at org.eclipse.ui.internal.SaveablesList.addModels(SaveablesList.java:289)
+ at org.eclipse.ui.internal.SaveablesList.postOpen(SaveablesList.java:695)
+ at org.eclipse.ui.internal.PartList.partOpened(PartList.java:234)
+ at org.eclipse.ui.internal.PartList.access$0(PartList.java:210)
+ at org.eclipse.ui.internal.PartList$1.propertyChanged(PartList.java:40)
+ at org.eclipse.ui.internal.WorkbenchPartReference.fireInternalPropertyChange(WorkbenchPartReference.java:375)
+ at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:610)
+ at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
+ at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
+ at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
+ at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
+ at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
+ at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1245)
+ at org.eclipse.ui.internal.PartStack.handleDeferredEvents(PartStack.java:1213)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.PartSashContainer.handleDeferredEvents(PartSashContainer.java:1409)
+ at org.eclipse.ui.internal.LayoutPart.deferUpdates(LayoutPart.java:400)
+ at org.eclipse.ui.internal.WorkbenchPage.handleDeferredEvents(WorkbenchPage.java:1495)
+ at org.eclipse.ui.internal.WorkbenchPage.deferUpdates(WorkbenchPage.java:1485)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditors(WorkbenchPage.java:1459)
+ at org.eclipse.ui.internal.WorkbenchPage.closeEditor(WorkbenchPage.java:1523)
+ at org.eclipse.ui.internal.CloseEditorHandler.execute(CloseEditorHandler.java:47)
+ at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
+ at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
+ at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
+ at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508)
+ at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123)
+ at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
+ at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1531)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1257)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1282)
+ at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1267)
+ at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1294)
+ at org.eclipse.swt.widgets.Widget.gtk_key_press_event(Widget.java:730)
+ at org.eclipse.swt.widgets.Control.gtk_key_press_event(Control.java:3019)
+ at org.eclipse.swt.widgets.Composite.gtk_key_press_event(Composite.java:734)
+ at org.eclipse.swt.widgets.Tree.gtk_key_press_event(Tree.java:2002)
+ at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1743)
+ at org.eclipse.swt.widgets.Control.windowProc(Control.java:5016)
+ at org.eclipse.swt.widgets.Tree.windowProc(Tree.java:3530)
+ at org.eclipse.swt.widgets.Display.windowProc(Display.java:4408)
+ at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8394)
+ at org.eclipse.swt.widgets.Display.eventProc(Display.java:1245)
+ at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method)
+ at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2258)
+ at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207)
+ at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
+ at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
+ at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
+ at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
+ at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
+ at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
+ at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
+ at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
+ at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
+ at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
+ at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:616)
+ at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
+ at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
+ at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
+ at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/.log b/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/.log
index 865b28a..e69fab0 100644
--- a/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/.log
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/.log
@@ -3,3 +3,4 @@
*** SESSION Oct 09, 2011 14:26:25.89 -------------------------------------------
*** SESSION Oct 10, 2011 15:16:10.81 -------------------------------------------
*** SESSION Feb 28, 2012 11:47:32.08 -------------------------------------------
+*** SESSION Feb 28, 2012 12:34:33.29 -------------------------------------------
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/CatcherDriver.1330426096136.pdom b/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/CatcherDriver.1330426096136.pdom
new file mode 100644
index 0000000..924efda
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.core/CatcherDriver.1330426096136.pdom
Binary files differ
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.make.core/CatcherDriver.sc b/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.make.core/CatcherDriver.sc
new file mode 100644
index 0000000..32f3d38
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.cdt.make.core/CatcherDriver.sc
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?scdStore version="2"?>
+
+<scannerInfo id="org.eclipse.cdt.make.core.discoveredScannerInfo">
+<instance id="0.91533971">
+<collector id="org.eclipse.cdt.make.core.PerProjectSICollector">
+<includePath path="/usr/lib/gcc/x86_64-linux-gnu/4.6.1/include"/>
+<includePath path="/usr/local/include"/>
+<includePath path="/usr/lib/gcc/x86_64-linux-gnu/4.6.1/include-fixed"/>
+<includePath path="/usr/include/x86_64-linux-gnu"/>
+<includePath path="/usr/include"/>
+<definedSymbol symbol="__STDC__=1"/>
+<definedSymbol symbol="__STDC_HOSTED__=1"/>
+<definedSymbol symbol="__GNUC__=4"/>
+<definedSymbol symbol="__GNUC_MINOR__=6"/>
+<definedSymbol symbol="__GNUC_PATCHLEVEL__=1"/>
+<definedSymbol symbol="__VERSION__=&quot;4.6.1&quot;"/>
+<definedSymbol symbol="__FINITE_MATH_ONLY__=0"/>
+<definedSymbol symbol="_LP64=1"/>
+<definedSymbol symbol="__LP64__=1"/>
+<definedSymbol symbol="__SIZEOF_INT__=4"/>
+<definedSymbol symbol="__SIZEOF_LONG__=8"/>
+<definedSymbol symbol="__SIZEOF_LONG_LONG__=8"/>
+<definedSymbol symbol="__SIZEOF_SHORT__=2"/>
+<definedSymbol symbol="__SIZEOF_FLOAT__=4"/>
+<definedSymbol symbol="__SIZEOF_DOUBLE__=8"/>
+<definedSymbol symbol="__SIZEOF_LONG_DOUBLE__=16"/>
+<definedSymbol symbol="__SIZEOF_SIZE_T__=8"/>
+<definedSymbol symbol="__CHAR_BIT__=8"/>
+<definedSymbol symbol="__BIGGEST_ALIGNMENT__=16"/>
+<definedSymbol symbol="__ORDER_LITTLE_ENDIAN__=1234"/>
+<definedSymbol symbol="__ORDER_BIG_ENDIAN__=4321"/>
+<definedSymbol symbol="__ORDER_PDP_ENDIAN__=3412"/>
+<definedSymbol symbol="__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__"/>
+<definedSymbol symbol="__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__"/>
+<definedSymbol symbol="__SIZEOF_POINTER__=8"/>
+<definedSymbol symbol="__SIZE_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__PTRDIFF_TYPE__=long int"/>
+<definedSymbol symbol="__WCHAR_TYPE__=int"/>
+<definedSymbol symbol="__WINT_TYPE__=unsigned int"/>
+<definedSymbol symbol="__INTMAX_TYPE__=long int"/>
+<definedSymbol symbol="__UINTMAX_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__CHAR16_TYPE__=short unsigned int"/>
+<definedSymbol symbol="__CHAR32_TYPE__=unsigned int"/>
+<definedSymbol symbol="__SIG_ATOMIC_TYPE__=int"/>
+<definedSymbol symbol="__INT8_TYPE__=signed char"/>
+<definedSymbol symbol="__INT16_TYPE__=short int"/>
+<definedSymbol symbol="__INT32_TYPE__=int"/>
+<definedSymbol symbol="__INT64_TYPE__=long int"/>
+<definedSymbol symbol="__UINT8_TYPE__=unsigned char"/>
+<definedSymbol symbol="__UINT16_TYPE__=short unsigned int"/>
+<definedSymbol symbol="__UINT32_TYPE__=unsigned int"/>
+<definedSymbol symbol="__UINT64_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__INT_LEAST8_TYPE__=signed char"/>
+<definedSymbol symbol="__INT_LEAST16_TYPE__=short int"/>
+<definedSymbol symbol="__INT_LEAST32_TYPE__=int"/>
+<definedSymbol symbol="__INT_LEAST64_TYPE__=long int"/>
+<definedSymbol symbol="__UINT_LEAST8_TYPE__=unsigned char"/>
+<definedSymbol symbol="__UINT_LEAST16_TYPE__=short unsigned int"/>
+<definedSymbol symbol="__UINT_LEAST32_TYPE__=unsigned int"/>
+<definedSymbol symbol="__UINT_LEAST64_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__INT_FAST8_TYPE__=signed char"/>
+<definedSymbol symbol="__INT_FAST16_TYPE__=long int"/>
+<definedSymbol symbol="__INT_FAST32_TYPE__=long int"/>
+<definedSymbol symbol="__INT_FAST64_TYPE__=long int"/>
+<definedSymbol symbol="__UINT_FAST8_TYPE__=unsigned char"/>
+<definedSymbol symbol="__UINT_FAST16_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__UINT_FAST32_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__UINT_FAST64_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__INTPTR_TYPE__=long int"/>
+<definedSymbol symbol="__UINTPTR_TYPE__=long unsigned int"/>
+<definedSymbol symbol="__GXX_ABI_VERSION=1002"/>
+<definedSymbol symbol="__SCHAR_MAX__=127"/>
+<definedSymbol symbol="__SHRT_MAX__=32767"/>
+<definedSymbol symbol="__INT_MAX__=2147483647"/>
+<definedSymbol symbol="__LONG_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__LONG_LONG_MAX__=9223372036854775807LL"/>
+<definedSymbol symbol="__WCHAR_MAX__=2147483647"/>
+<definedSymbol symbol="__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)"/>
+<definedSymbol symbol="__WINT_MAX__=4294967295U"/>
+<definedSymbol symbol="__WINT_MIN__=0U"/>
+<definedSymbol symbol="__PTRDIFF_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__SIZE_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__INTMAX_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__INTMAX_C(c)=c ## L"/>
+<definedSymbol symbol="__UINTMAX_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__UINTMAX_C(c)=c ## UL"/>
+<definedSymbol symbol="__SIG_ATOMIC_MAX__=2147483647"/>
+<definedSymbol symbol="__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)"/>
+<definedSymbol symbol="__INT8_MAX__=127"/>
+<definedSymbol symbol="__INT16_MAX__=32767"/>
+<definedSymbol symbol="__INT32_MAX__=2147483647"/>
+<definedSymbol symbol="__INT64_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__UINT8_MAX__=255"/>
+<definedSymbol symbol="__UINT16_MAX__=65535"/>
+<definedSymbol symbol="__UINT32_MAX__=4294967295U"/>
+<definedSymbol symbol="__UINT64_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__INT_LEAST8_MAX__=127"/>
+<definedSymbol symbol="__INT8_C(c)=c"/>
+<definedSymbol symbol="__INT_LEAST16_MAX__=32767"/>
+<definedSymbol symbol="__INT16_C(c)=c"/>
+<definedSymbol symbol="__INT_LEAST32_MAX__=2147483647"/>
+<definedSymbol symbol="__INT32_C(c)=c"/>
+<definedSymbol symbol="__INT_LEAST64_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__INT64_C(c)=c ## L"/>
+<definedSymbol symbol="__UINT_LEAST8_MAX__=255"/>
+<definedSymbol symbol="__UINT8_C(c)=c"/>
+<definedSymbol symbol="__UINT_LEAST16_MAX__=65535"/>
+<definedSymbol symbol="__UINT16_C(c)=c"/>
+<definedSymbol symbol="__UINT_LEAST32_MAX__=4294967295U"/>
+<definedSymbol symbol="__UINT32_C(c)=c ## U"/>
+<definedSymbol symbol="__UINT_LEAST64_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__UINT64_C(c)=c ## UL"/>
+<definedSymbol symbol="__INT_FAST8_MAX__=127"/>
+<definedSymbol symbol="__INT_FAST16_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__INT_FAST32_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__INT_FAST64_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__UINT_FAST8_MAX__=255"/>
+<definedSymbol symbol="__UINT_FAST16_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__UINT_FAST32_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__UINT_FAST64_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__INTPTR_MAX__=9223372036854775807L"/>
+<definedSymbol symbol="__UINTPTR_MAX__=18446744073709551615UL"/>
+<definedSymbol symbol="__FLT_EVAL_METHOD__=0"/>
+<definedSymbol symbol="__DEC_EVAL_METHOD__=2"/>
+<definedSymbol symbol="__FLT_RADIX__=2"/>
+<definedSymbol symbol="__FLT_MANT_DIG__=24"/>
+<definedSymbol symbol="__FLT_DIG__=6"/>
+<definedSymbol symbol="__FLT_MIN_EXP__=(-125)"/>
+<definedSymbol symbol="__FLT_MIN_10_EXP__=(-37)"/>
+<definedSymbol symbol="__FLT_MAX_EXP__=128"/>
+<definedSymbol symbol="__FLT_MAX_10_EXP__=38"/>
+<definedSymbol symbol="__FLT_DECIMAL_DIG__=9"/>
+<definedSymbol symbol="__FLT_MAX__=3.40282346638528859812e+38F"/>
+<definedSymbol symbol="__FLT_MIN__=1.17549435082228750797e-38F"/>
+<definedSymbol symbol="__FLT_EPSILON__=1.19209289550781250000e-7F"/>
+<definedSymbol symbol="__FLT_DENORM_MIN__=1.40129846432481707092e-45F"/>
+<definedSymbol symbol="__FLT_HAS_DENORM__=1"/>
+<definedSymbol symbol="__FLT_HAS_INFINITY__=1"/>
+<definedSymbol symbol="__FLT_HAS_QUIET_NAN__=1"/>
+<definedSymbol symbol="__DBL_MANT_DIG__=53"/>
+<definedSymbol symbol="__DBL_DIG__=15"/>
+<definedSymbol symbol="__DBL_MIN_EXP__=(-1021)"/>
+<definedSymbol symbol="__DBL_MIN_10_EXP__=(-307)"/>
+<definedSymbol symbol="__DBL_MAX_EXP__=1024"/>
+<definedSymbol symbol="__DBL_MAX_10_EXP__=308"/>
+<definedSymbol symbol="__DBL_DECIMAL_DIG__=17"/>
+<definedSymbol symbol="__DBL_MAX__=((double)1.79769313486231570815e+308L)"/>
+<definedSymbol symbol="__DBL_MIN__=((double)2.22507385850720138309e-308L)"/>
+<definedSymbol symbol="__DBL_EPSILON__=((double)2.22044604925031308085e-16L)"/>
+<definedSymbol symbol="__DBL_DENORM_MIN__=((double)4.94065645841246544177e-324L)"/>
+<definedSymbol symbol="__DBL_HAS_DENORM__=1"/>
+<definedSymbol symbol="__DBL_HAS_INFINITY__=1"/>
+<definedSymbol symbol="__DBL_HAS_QUIET_NAN__=1"/>
+<definedSymbol symbol="__LDBL_MANT_DIG__=64"/>
+<definedSymbol symbol="__LDBL_DIG__=18"/>
+<definedSymbol symbol="__LDBL_MIN_EXP__=(-16381)"/>
+<definedSymbol symbol="__LDBL_MIN_10_EXP__=(-4931)"/>
+<definedSymbol symbol="__LDBL_MAX_EXP__=16384"/>
+<definedSymbol symbol="__LDBL_MAX_10_EXP__=4932"/>
+<definedSymbol symbol="__DECIMAL_DIG__=21"/>
+<definedSymbol symbol="__LDBL_MAX__=1.18973149535723176502e+4932L"/>
+<definedSymbol symbol="__LDBL_MIN__=3.36210314311209350626e-4932L"/>
+<definedSymbol symbol="__LDBL_EPSILON__=1.08420217248550443401e-19L"/>
+<definedSymbol symbol="__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L"/>
+<definedSymbol symbol="__LDBL_HAS_DENORM__=1"/>
+<definedSymbol symbol="__LDBL_HAS_INFINITY__=1"/>
+<definedSymbol symbol="__LDBL_HAS_QUIET_NAN__=1"/>
+<definedSymbol symbol="__DEC32_MANT_DIG__=7"/>
+<definedSymbol symbol="__DEC32_MIN_EXP__=(-94)"/>
+<definedSymbol symbol="__DEC32_MAX_EXP__=97"/>
+<definedSymbol symbol="__DEC32_MIN__=1E-95DF"/>
+<definedSymbol symbol="__DEC32_MAX__=9.999999E96DF"/>
+<definedSymbol symbol="__DEC32_EPSILON__=1E-6DF"/>
+<definedSymbol symbol="__DEC32_SUBNORMAL_MIN__=0.000001E-95DF"/>
+<definedSymbol symbol="__DEC64_MANT_DIG__=16"/>
+<definedSymbol symbol="__DEC64_MIN_EXP__=(-382)"/>
+<definedSymbol symbol="__DEC64_MAX_EXP__=385"/>
+<definedSymbol symbol="__DEC64_MIN__=1E-383DD"/>
+<definedSymbol symbol="__DEC64_MAX__=9.999999999999999E384DD"/>
+<definedSymbol symbol="__DEC64_EPSILON__=1E-15DD"/>
+<definedSymbol symbol="__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD"/>
+<definedSymbol symbol="__DEC128_MANT_DIG__=34"/>
+<definedSymbol symbol="__DEC128_MIN_EXP__=(-6142)"/>
+<definedSymbol symbol="__DEC128_MAX_EXP__=6145"/>
+<definedSymbol symbol="__DEC128_MIN__=1E-6143DL"/>
+<definedSymbol symbol="__DEC128_MAX__=9.999999999999999999999999999999999E6144DL"/>
+<definedSymbol symbol="__DEC128_EPSILON__=1E-33DL"/>
+<definedSymbol symbol="__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL"/>
+<definedSymbol symbol="__REGISTER_PREFIX__="/>
+<definedSymbol symbol="__USER_LABEL_PREFIX__="/>
+<definedSymbol symbol="_FORTIFY_SOURCE=2"/>
+<definedSymbol symbol="__GNUC_GNU_INLINE__=1"/>
+<definedSymbol symbol="__NO_INLINE__=1"/>
+<definedSymbol symbol="__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1"/>
+<definedSymbol symbol="__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1"/>
+<definedSymbol symbol="__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1"/>
+<definedSymbol symbol="__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1"/>
+<definedSymbol symbol="__GCC_HAVE_DWARF2_CFI_ASM=1"/>
+<definedSymbol symbol="__PRAGMA_REDEFINE_EXTNAME=1"/>
+<definedSymbol symbol="__SSP__=1"/>
+<definedSymbol symbol="__SIZEOF_INT128__=16"/>
+<definedSymbol symbol="__SIZEOF_WCHAR_T__=4"/>
+<definedSymbol symbol="__SIZEOF_WINT_T__=4"/>
+<definedSymbol symbol="__SIZEOF_PTRDIFF_T__=8"/>
+<definedSymbol symbol="__amd64=1"/>
+<definedSymbol symbol="__amd64__=1"/>
+<definedSymbol symbol="__x86_64=1"/>
+<definedSymbol symbol="__x86_64__=1"/>
+<definedSymbol symbol="__k8=1"/>
+<definedSymbol symbol="__k8__=1"/>
+<definedSymbol symbol="__MMX__=1"/>
+<definedSymbol symbol="__SSE__=1"/>
+<definedSymbol symbol="__SSE2__=1"/>
+<definedSymbol symbol="__SSE_MATH__=1"/>
+<definedSymbol symbol="__SSE2_MATH__=1"/>
+<definedSymbol symbol="__gnu_linux__=1"/>
+<definedSymbol symbol="__linux=1"/>
+<definedSymbol symbol="__linux__=1"/>
+<definedSymbol symbol="linux=1"/>
+<definedSymbol symbol="__unix=1"/>
+<definedSymbol symbol="__unix__=1"/>
+<definedSymbol symbol="unix=1"/>
+<definedSymbol symbol="__ELF__=1"/>
+<definedSymbol symbol="__DECIMAL_BID_FORMAT__=1"/>
+</collector>
+</instance>
+</scannerInfo>
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/36/a07dff68fd6100111a83ded3e22caa93 b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/36/a07dff68fd6100111a83ded3e22caa93
new file mode 100644
index 0000000..7050c59
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/36/a07dff68fd6100111a83ded3e22caa93
@@ -0,0 +1,823 @@
+/* Cell Scanning code for OsmocomBB */
+
+/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+#include <l1ctl_proto.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/signal.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/rsl.h>
+
+#include <osmocom/bb/common/l1ctl.h>
+#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/bb/common/lapdm.h>
+#include <osmocom/bb/common/logging.h>
+#include <osmocom/bb/common/networks.h>
+#include <osmocom/bb/common/gps.h>
+#include <osmocom/bb/misc/cell_log.h>
+#include "../../../gsmmap/geo.h"
+
+#define READ_WAIT 2, 0
+#define RACH_WAIT 0, 900000
+#define MIN_RXLEV -106
+#define MAX_DIST 2000
+
+enum {
+ SCAN_STATE_PM,
+ SCAN_STATE_SYNC,
+ SCAN_STATE_READ,
+ SCAN_STATE_RACH,
+};
+
+/* ranges of bands */
+static uint16_t band_range[][2] = {{0, 124}, {512, 885}, {955, 1023}, {0, 0}};
+
+#define INFO_FLG_PM 1
+#define INFO_FLG_SYNC 2
+#define INFO_FLG_SI1 4
+#define INFO_FLG_SI2 8
+#define INFO_FLG_SI2bis 16
+#define INFO_FLG_SI2ter 32
+#define INFO_FLG_SI3 64
+#define INFO_FLG_SI4 128
+
+static struct osmocom_ms *ms;
+static struct osmo_timer_list timer;
+
+static struct pm_info {
+ uint16_t flags;
+ int8_t rxlev;
+} pm[1024];
+
+static int started = 0;
+static int state;
+static int8_t min_rxlev = MIN_RXLEV;
+static int sync_count;
+static int pm_index, pm_gps_valid;
+static double pm_gps_x, pm_gps_y, pm_gps_z;
+static int arfcn;
+static int rach_count;
+static FILE *logfp = NULL;
+extern char *logname;
+extern int RACH_MAX;
+
+
+static struct gsm48_sysinfo sysinfo;
+
+static struct log_si {
+ uint16_t flags;
+ uint8_t bsic;
+ int8_t rxlev;
+ uint16_t mcc, mnc, lac, cellid;
+ uint8_t ta;
+ double latitude, longitude;
+} log_si;
+
+struct rach_ref {
+ uint8_t valid;
+ uint8_t cr;
+ uint8_t t1, t2, t3;
+} rach_ref;
+
+#define LOGFILE(fmt, args...) \
+ fprintf(logfp, fmt, ## args);
+#define LOGFLUSH() \
+ fflush(logfp);
+
+static void start_sync(void);
+static void start_rach(void);
+static void start_pm(void);
+
+static void log_gps(void)
+{
+ if (!g.enable || !g.valid)
+ return;
+ LOGFILE("position %.8f %.8f\n", g.longitude, g.latitude);
+}
+
+static void log_time(void)
+{
+ time_t now;
+
+ if (g.enable && g.valid)
+ now = g.gmt;
+ else
+ time(&now);
+ LOGFILE("time %lu\n", now);
+}
+
+static void log_frame(char *tag, uint8_t *data)
+{
+ int i;
+
+ LOGFILE("%s", tag);
+ for (i = 0; i < 23; i++)
+ LOGFILE(" %02x", *data++);
+ LOGFILE("\n");
+}
+
+static void log_pm(void)
+{
+ int count = 0, i;
+
+ LOGFILE("[power]\n");
+ log_time();
+ log_gps();
+ for (i = 0; i <= 1023; i++) {
+ if ((pm[i].flags & INFO_FLG_PM)) {
+ if (!count)
+ LOGFILE("arfcn %d", i);
+ LOGFILE(" %d", pm[i].rxlev);
+ count++;
+ if (count == 12) {
+ LOGFILE("\n");
+ count = 0;
+ }
+ } else {
+ if (count) {
+ LOGFILE("\n");
+ count = 0;
+ }
+ }
+ }
+ if (count)
+ LOGFILE("\n");
+
+ LOGFILE("\n");
+ LOGFLUSH();
+}
+
+static void log_sysinfo(void)
+{
+ struct rx_meas_stat *meas = &ms->meas;
+ struct gsm48_sysinfo *s = &sysinfo;
+ int8_t rxlev;
+ char ta_str[32] = "";
+
+ if (log_si.ta != 0xff)
+ sprintf(ta_str, " TA=%d", log_si.ta);
+
+ //LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n",
+ // arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc),
+ // gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str);
+
+ LOGFILE("[SysInfo]\n");
+ LOGFILE("country %s\n", gsm_get_mcc(s->mcc))
+ LOGFILE("provider %s\n", gsm_get_mnc(s->mcc, s->mnc))
+ LOGFILE("arfcn %d\n", s->arfcn);
+ //log_time();
+ //log_gps();
+ //LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7);
+ rxlev = meas->rxlev / meas->frames - 110;
+ LOGFILE("rxlev %d\n", rxlev);
+ //if (s->si1)
+ // log_frame("si1", s->si1_msg);
+ if (s->si2)
+ log_frame("si2", s->si2_msg);
+ if (s->si2bis)
+ log_frame("si2bis", s->si2b_msg);
+ if (s->si2ter)
+ log_frame("si2ter", s->si2t_msg);
+ //if (s->si3)
+ // log_frame("si3", s->si3_msg);
+ //if (s->si4)
+ // log_frame("si4", s->si4_msg);
+ //if (log_si.ta != 0xff)
+ // LOGFILE("ta %d\n", log_si.ta);
+ LOGFILE("[EndInfo]\n");
+ LOGFILE("\n");
+ LOGFLUSH();
+}
+
+static void timeout_cb(void *arg)
+{
+ switch (state) {
+ case SCAN_STATE_READ:
+ LOGP(DRR, LOGL_INFO, "Timeout reading BCCH\n");
+ start_sync();
+ break;
+ case SCAN_STATE_RACH:
+ LOGP(DRR, LOGL_INFO, "Timeout on RACH\n");
+ rach_count++;
+ start_rach();
+ break;
+ }
+}
+
+static void stop_timer(void)
+{
+ if (osmo_timer_pending(&timer))
+ osmo_timer_del(&timer);
+}
+
+static void start_timer(int sec, int micro)
+{
+ stop_timer();
+ timer.cb = timeout_cb;
+ timer.data = ms;
+ osmo_timer_schedule(&timer, sec, micro);
+}
+
+static void start_rach(void)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+ uint8_t chan_req_val, chan_req_mask;
+ struct msgb *nmsg;
+ struct abis_rsl_cchan_hdr *ncch;
+
+ if (rach_count == RACH_MAX) {
+ log_sysinfo();
+ start_sync();
+ return;
+ }
+
+ state = SCAN_STATE_RACH;
+
+ if (s->neci) {
+ chan_req_mask = 0x0f;
+ chan_req_val = 0x01;
+ LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
+ "(OTHER with NECI)\n", chan_req_val);
+ } else {
+ chan_req_mask = 0x1f;
+ chan_req_val = 0xe0;
+ LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER no NECI)\n",
+ chan_req_val);
+ }
+
+ rach_ref.valid = 0;
+ rach_ref.cr = random();
+ rach_ref.cr &= chan_req_mask;
+ rach_ref.cr |= chan_req_val;
+
+ nmsg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
+ RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
+ if (!nmsg)
+ return;
+ nmsg->l2h = nmsg->data;
+ ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
+ + 4 + 2 + 2);
+ rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
+ ncch->chan_nr = RSL_CHAN_RACH;
+ ncch->data[0] = RSL_IE_REQ_REFERENCE;
+ ncch->data[1] = rach_ref.cr;
+ ncch->data[2] = (s->ccch_conf == 1) << 7;
+ ncch->data[3] = 0;
+ ncch->data[4] = RSL_IE_ACCESS_DELAY;
+ ncch->data[5] = 0; /* no delay */
+ ncch->data[6] = RSL_IE_MS_POWER;
+ ncch->data[7] = 0; /* full power */
+
+ start_timer(RACH_WAIT);
+
+ lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
+}
+
+static void start_sync(void)
+{
+ int rxlev = -128;
+ int i, dist = 0;
+ char dist_str[32] = "";
+
+ arfcn = 0xffff;
+ for (i = 0; i <= 1023; i++) {
+ if ((pm[i].flags & INFO_FLG_PM)
+ && !(pm[i].flags & INFO_FLG_SYNC)) {
+ if (pm[i].rxlev > rxlev) {
+ rxlev = pm[i].rxlev;
+ arfcn = i;
+ }
+ }
+ }
+ /* if GPS becomes valid, like after exitting a tunnel */
+ if (!pm_gps_valid && g.valid) {
+ pm_gps_valid = 1;
+ geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z, g.longitude,
+ g.latitude);
+ }
+ if (pm_gps_valid && g.valid) {
+ double x, y, z;
+
+ geo2space(&x, &y, &z, g.longitude, g.latitude);
+ dist = distinspace(pm_gps_x, pm_gps_y, pm_gps_z, x, y, z);
+ sprintf(dist_str, " dist %d", (int)dist);
+ }
+ if (dist > MAX_DIST || arfcn == 0xffff || rxlev < min_rxlev) {
+ memset(pm, 0, sizeof(pm));
+ pm_index = 0;
+ sync_count = 0;
+ start_pm();
+ return;
+ }
+ pm[arfcn].flags |= INFO_FLG_SYNC;
+ //HACK: no use for us right now
+ LOGP(DSUM, LOGL_INFO, "Sync ARFCN %d (rxlev %d, %d syncs "
+ "left)%s\n", arfcn, pm[arfcn].rxlev, sync_count--, dist_str);
+ memset(&sysinfo, 0, sizeof(sysinfo));
+ sysinfo.arfcn = arfcn;
+ state = SCAN_STATE_SYNC;
+ l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
+ l1ctl_tx_fbsb_req(ms, arfcn, L1CTL_FBSB_F_FB01SB, 100, 0,
+ CCCH_MODE_NONE);
+}
+
+static void start_pm(void)
+{
+ uint16_t from, to;
+
+ state = SCAN_STATE_PM;
+ from = band_range[pm_index][0];
+ to = band_range[pm_index][1];
+
+ if (from == 0 && to == 0) {
+ LOGP(DSUM, LOGL_INFO, "Measurement done\n");
+ pm_gps_valid = g.enable && g.valid;
+ if (pm_gps_valid)
+ geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z,
+ g.longitude, g.latitude);
+ log_pm();
+ start_sync();
+ return;
+ }
+ LOGP(DSUM, LOGL_INFO, "Measure from %d to %d\n", from, to);
+ l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
+ l1ctl_tx_pm_req_range(ms, from, to);
+}
+
+static int signal_cb(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
+{
+ struct osmobb_meas_res *mr;
+ struct osmobb_fbsb_res *fr;
+ uint16_t index;
+
+ if (subsys != SS_L1CTL)
+ return 0;
+
+ switch (signal) {
+ case S_L1CTL_PM_RES:
+ mr = signal_data;
+ index = mr->band_arfcn & 0x3ff;
+ pm[index].flags |= INFO_FLG_PM;
+ pm[index].rxlev = mr->rx_lev - 110;
+ if (pm[index].rxlev >= min_rxlev)
+ sync_count++;
+// printf("rxlev %d = %d (sync_count %d)\n", index, pm[index].rxlev, sync_count);
+ break;
+ case S_L1CTL_PM_DONE:
+ pm_index++;
+ start_pm();
+ break;
+ case S_L1CTL_FBSB_RESP:
+ fr = signal_data;
+ sysinfo.bsic = fr->bsic;
+ state = SCAN_STATE_READ;
+ memset(&ms->meas, 0, sizeof(ms->meas));
+ memset(&log_si, 0, sizeof(log_si));
+ log_si.flags |= INFO_FLG_SYNC;
+ log_si.ta = 0xff; /* invalid */
+ start_timer(READ_WAIT);
+ LOGP(DRR, LOGL_INFO, "Synchronized, start reading\n");
+ break;
+ case S_L1CTL_FBSB_ERR:
+ LOGP(DRR, LOGL_INFO, "Sync failed\n");
+ start_sync();
+ break;
+ case S_L1CTL_RESET:
+ if (started)
+ break;
+ started = 1;
+ memset(pm, 0, sizeof(pm));
+ pm_index = 0;
+ sync_count = 0;
+ start_pm();
+ }
+ return 0;
+}
+
+static int ta_result(uint8_t ta)
+{
+ stop_timer();
+
+ if (ta == 0xff)
+ LOGP(DSUM, LOGL_INFO, "Got assignment reject\n");
+ else {
+ LOGP(DSUM, LOGL_DEBUG, "Got assignment TA = %d\n", ta);
+ log_si.ta = ta;
+ }
+
+ log_sysinfo();
+ start_sync();
+
+ return 0;
+}
+
+/* match request reference agains request */
+static int match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
+{
+ uint8_t ia_t1, ia_t2, ia_t3;
+
+ /* filter confirmed RACH requests only */
+ if (rach_ref.valid && ref->ra == rach_ref.cr) {
+ ia_t1 = ref->t1;
+ ia_t2 = ref->t2;
+ ia_t3 = (ref->t3_high << 3) | ref->t3_low;
+ if (ia_t1 == rach_ref.t1 && ia_t2 == rach_ref.t2
+ && ia_t3 == rach_ref.t3) {
+ LOGP(DRR, LOGL_INFO, "request %02x matches "
+ "(fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2,
+ ia_t3);
+ return 1;
+ } else
+ LOGP(DRR, LOGL_INFO, "request %02x matches but not "
+ "frame number (IMM.ASS fn=%d,%d,%d != RACH "
+ "fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2, ia_t3,
+ rach_ref.t1, rach_ref.t2, rach_ref.t3);
+ }
+
+ return 0;
+}
+
+/* 9.1.18 IMMEDIATE ASSIGNMENT is received */
+static int imm_ass(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_imm_ass *ia = msgb_l3(msg);
+
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT:\n");
+
+ if (state != SCAN_STATE_RACH) {
+ LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
+ return 0;
+ }
+
+ /* request ref */
+ if (match_ra(ms, &ia->req_ref)) {
+ return ta_result(ia->timing_advance);
+ }
+ LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
+
+ return 0;
+}
+
+/* 9.1.19 IMMEDIATE ASSIGNMENT EXTENDED is received */
+static int imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
+
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT EXTENDED:\n");
+
+ if (state != SCAN_STATE_RACH) {
+ LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
+ return 0;
+ }
+
+ /* request ref 1 */
+ if (match_ra(ms, &ia->req_ref1)) {
+ return ta_result(ia->timing_advance1);
+ }
+ /* request ref 2 */
+ if (match_ra(ms, &ia->req_ref2)) {
+ return ta_result(ia->timing_advance2);
+ }
+ LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
+
+ return 0;
+}
+
+/* 9.1.20 IMMEDIATE ASSIGNMENT REJECT is received */
+static int imm_ass_rej(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
+ int i;
+ struct gsm48_req_ref *req_ref;
+
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT:\n");
+
+ if (state != SCAN_STATE_RACH) {
+ LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
+ return 0;
+ }
+
+ for (i = 0; i < 4; i++) {
+ /* request reference */
+ req_ref = (struct gsm48_req_ref *)
+ (((uint8_t *)&ia->req_ref1) + i * 4);
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT "
+ "(ref 0x%02x)\n", req_ref->ra);
+ if (match_ra(ms, req_ref)) {
+ return ta_result(0xff);
+ }
+ }
+
+ return 0;
+}
+
+/* receive CCCH at RR layer */
+static int pch_agch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
+
+ switch (sih->system_information) {
+ case GSM48_MT_RR_PAG_REQ_1:
+ case GSM48_MT_RR_PAG_REQ_2:
+ case GSM48_MT_RR_PAG_REQ_3:
+ return 0;
+ case GSM48_MT_RR_IMM_ASS:
+ return imm_ass(ms, msg);
+ case GSM48_MT_RR_IMM_ASS_EXT:
+ return imm_ass_ext(ms, msg);
+ case GSM48_MT_RR_IMM_ASS_REJ:
+ return imm_ass_rej(ms, msg);
+ default:
+ return -EINVAL;
+ }
+}
+
+/* check if sysinfo is complete, change to RACH state */
+static int new_sysinfo(void)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+
+ /* restart timer */
+ start_timer(READ_WAIT);
+
+ /* mandatory */
+ if (!s->si1 || !s->si2 || !s->si3 || !s->si4) {
+ LOGP(DRR, LOGL_INFO, "not all mandatory SI received\n");
+ return 0;
+ }
+
+ /* extended band */
+ if (s->nb_ext_ind_si2 && !s->si2bis) {
+ LOGP(DRR, LOGL_INFO, "extended ba, but si2bis not received\n");
+ return 0;
+ }
+
+ /* 2ter */
+ if (s->si2ter_ind && !s->si2ter) {
+ LOGP(DRR, LOGL_INFO, "si2ter_ind, but si2ter not received\n");
+ return 0;
+ }
+
+ LOGP(DRR, LOGL_INFO, "Sysinfo complete\n");
+
+ stop_timer();
+
+ rach_count = 0;
+ start_rach();
+
+ return 0;
+}
+
+/* receive BCCH at RR layer */
+static int bcch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
+ uint8_t ccch_mode;
+
+ if (msgb_l3len(msg) != 23) {
+ LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n");
+ return -EINVAL;
+ }
+ switch (sih->system_information) {
+ case GSM48_MT_RR_SYSINFO_1:
+ if (!memcmp(sih, s->si1_msg, sizeof(s->si1_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
+ gsm48_decode_sysinfo1(s,
+ (struct gsm48_system_information_type_1 *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_2:
+ if (!memcmp(sih, s->si2_msg, sizeof(s->si2_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
+ gsm48_decode_sysinfo2(s,
+ (struct gsm48_system_information_type_2 *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_2bis:
+ if (!memcmp(sih, s->si2b_msg, sizeof(s->si2b_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
+ gsm48_decode_sysinfo2bis(s,
+ (struct gsm48_system_information_type_2bis *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_2ter:
+ if (!memcmp(sih, s->si2t_msg, sizeof(s->si2t_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
+ gsm48_decode_sysinfo2ter(s,
+ (struct gsm48_system_information_type_2ter *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_3:
+ if (!memcmp(sih, s->si3_msg, sizeof(s->si3_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 3\n");
+ gsm48_decode_sysinfo3(s,
+ (struct gsm48_system_information_type_3 *) sih,
+ msgb_l3len(msg));
+ ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
+ CCCH_MODE_NON_COMBINED;
+ LOGP(DRR, LOGL_INFO, "Changing CCCH_MODE to %d\n", ccch_mode);
+ l1ctl_tx_ccch_mode_req(ms, ccch_mode);
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_4:
+ if (!memcmp(sih, s->si4_msg, sizeof(s->si4_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
+ gsm48_decode_sysinfo4(s,
+ (struct gsm48_system_information_type_4 *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ default:
+ return -EINVAL;
+ }
+}
+
+static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ struct tlv_parsed tv;
+ uint8_t ch_type, ch_subch, ch_ts;
+
+ DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
+ rllh->chan_nr, rllh->link_id);
+
+ rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
+ if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
+ DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
+ return -EIO;
+ }
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
+
+ if (state != SCAN_STATE_READ && state != SCAN_STATE_RACH) {
+ return -EINVAL;
+ }
+
+ rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
+ switch (ch_type) {
+ case RSL_CHAN_PCH_AGCH:
+ return pch_agch(ms, msg);
+ case RSL_CHAN_BCCH:
+ return bcch(ms, msg);
+#if 0
+ case RSL_CHAN_Bm_ACCHs:
+ case RSL_CHAN_Lm_ACCHs:
+ case RSL_CHAN_SDCCH4_ACCH:
+ case RSL_CHAN_SDCCH8_ACCH:
+ return rx_acch(ms, msg);
+#endif
+ default:
+ LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
+ rllh->chan_nr);
+ return -EINVAL;
+ }
+}
+
+static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ int msg_type = rllh->c.msg_type;
+
+ if (msg_type == RSL_MT_UNIT_DATA_IND) {
+ unit_data_ind(ms, msg);
+ } else
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
+
+ msgb_free(msg);
+
+ return 0;
+}
+
+int chan_conf(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
+ struct gsm48_req_ref *ref = (struct gsm48_req_ref *) (ch->data + 1);
+
+ if (msgb_l2len(msg) < sizeof(*ch) + sizeof(*ref)) {
+ LOGP(DRR, LOGL_ERROR, "CHAN_CNF too slort\n");
+ return -EINVAL;
+ }
+
+ rach_ref.valid = 1;
+ rach_ref.t1 = ref->t1;
+ rach_ref.t2 = ref->t2;
+ rach_ref.t3 = ref->t3_low | (ref->t3_high << 3);
+
+ return 0;
+}
+
+static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
+ int msg_type = ch->c.msg_type;
+ int rc;
+
+ LOGP(DRSL, LOGL_INFO, "Received '%s' from layer1\n",
+ rsl_msg_name(msg_type));
+
+ if (state == SCAN_STATE_RACH && msg_type == RSL_MT_CHAN_CONF) {
+ rc = chan_conf(ms, msg);
+ msgb_free(msg);
+ return rc;
+ }
+
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
+ msgb_free(msg);
+ return 0;
+}
+
+static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
+{
+ struct osmocom_ms *ms = l3ctx;
+ struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
+ int rc = 0;
+
+ switch (rslh->msg_discr & 0xfe) {
+ case ABIS_RSL_MDISC_RLL:
+ rc = rcv_rll(ms, msg);
+ break;
+ case ABIS_RSL_MDISC_COM_CHAN:
+ rc = rcv_cch(ms, msg);
+ break;
+ default:
+ LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
+ rslh->msg_discr);
+ msgb_free(msg);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+int scan_init(struct osmocom_ms *_ms)
+{
+ ms = _ms;
+ osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
+ memset(&timer, 0, sizeof(timer));
+ lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
+ g.enable = 1;
+ osmo_gps_init();
+ if (osmo_gps_open())
+ g.enable = 0;
+
+ if (!strcmp(logname, "-"))
+ logfp = stdout;
+ else
+ logfp = fopen(logname, "a");
+ if (!logfp) {
+ fprintf(stderr, "Failed to open logfile '%s'\n", logname);
+ scan_exit();
+ return -errno;
+ }
+ LOGP(DSUM, LOGL_INFO, "Scanner initialized\n");
+
+ return 0;
+}
+
+int scan_exit(void)
+{
+ LOGP(DSUM, LOGL_INFO, "Scanner exit\n");
+ if (g.valid)
+ osmo_gps_close();
+ if (logfp)
+ fclose(logfp);
+ osmo_signal_unregister_handler(SS_L1CTL, &signal_cb, NULL);
+ stop_timer();
+
+ return 0;
+}
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/c9/f0b573ecfa6100111a83ded3e22caa93 b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/c9/f0b573ecfa6100111a83ded3e22caa93
new file mode 100644
index 0000000..00ed944
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.history/c9/f0b573ecfa6100111a83ded3e22caa93
@@ -0,0 +1,824 @@
+/* Cell Scanning code for OsmocomBB */
+
+/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+#include <l1ctl_proto.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/signal.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/rsl.h>
+
+#include <osmocom/bb/common/l1ctl.h>
+#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/bb/common/lapdm.h>
+#include <osmocom/bb/common/logging.h>
+#include <osmocom/bb/common/networks.h>
+#include <osmocom/bb/common/gps.h>
+#include <osmocom/bb/misc/cell_log.h>
+#include "../../../gsmmap/geo.h"
+
+#define READ_WAIT 2, 0
+#define RACH_WAIT 0, 900000
+#define MIN_RXLEV -106
+#define MAX_DIST 2000
+
+enum {
+ SCAN_STATE_PM,
+ SCAN_STATE_SYNC,
+ SCAN_STATE_READ,
+ SCAN_STATE_RACH,
+};
+
+/* ranges of bands */
+static uint16_t band_range[][2] = {{0, 124}, {512, 885}, {955, 1023}, {0, 0}};
+
+#define INFO_FLG_PM 1
+#define INFO_FLG_SYNC 2
+#define INFO_FLG_SI1 4
+#define INFO_FLG_SI2 8
+#define INFO_FLG_SI2bis 16
+#define INFO_FLG_SI2ter 32
+#define INFO_FLG_SI3 64
+#define INFO_FLG_SI4 128
+
+static struct osmocom_ms *ms;
+static struct osmo_timer_list timer;
+
+static struct pm_info {
+ uint16_t flags;
+ int8_t rxlev;
+} pm[1024];
+
+static int started = 0;
+static int state;
+static int8_t min_rxlev = MIN_RXLEV;
+static int sync_count;
+static int pm_index, pm_gps_valid;
+static double pm_gps_x, pm_gps_y, pm_gps_z;
+static int arfcn;
+static int rach_count;
+static FILE *logfp = NULL;
+extern char *logname;
+extern int RACH_MAX;
+
+
+static struct gsm48_sysinfo sysinfo;
+
+static struct log_si {
+ uint16_t flags;
+ uint8_t bsic;
+ int8_t rxlev;
+ uint16_t mcc, mnc, lac, cellid;
+ uint8_t ta;
+ double latitude, longitude;
+} log_si;
+
+struct rach_ref {
+ uint8_t valid;
+ uint8_t cr;
+ uint8_t t1, t2, t3;
+} rach_ref;
+
+#define LOGFILE(fmt, args...) \
+ fprintf(logfp, fmt, ## args);
+#define LOGFLUSH() \
+ fflush(logfp);
+
+static void start_sync(void);
+static void start_rach(void);
+static void start_pm(void);
+
+static void log_gps(void)
+{
+ if (!g.enable || !g.valid)
+ return;
+ LOGFILE("position %.8f %.8f\n", g.longitude, g.latitude);
+}
+
+static void log_time(void)
+{
+ time_t now;
+
+ if (g.enable && g.valid)
+ now = g.gmt;
+ else
+ time(&now);
+ LOGFILE("time %lu\n", now);
+}
+
+static void log_frame(char *tag, uint8_t *data)
+{
+ int i;
+
+ LOGFILE("%s", tag);
+ for (i = 0; i < 23; i++)
+ LOGFILE(" %02x", *data++);
+ LOGFILE("\n");
+}
+
+static void log_pm(void)
+{
+ int count = 0, i;
+
+ LOGFILE("[power]\n");
+ log_time();
+ log_gps();
+ for (i = 0; i <= 1023; i++) {
+ if ((pm[i].flags & INFO_FLG_PM)) {
+ if (!count)
+ LOGFILE("arfcn %d", i);
+ LOGFILE(" %d", pm[i].rxlev);
+ count++;
+ if (count == 12) {
+ LOGFILE("\n");
+ count = 0;
+ }
+ } else {
+ if (count) {
+ LOGFILE("\n");
+ count = 0;
+ }
+ }
+ }
+ if (count)
+ LOGFILE("\n");
+
+ LOGFILE("\n");
+ LOGFLUSH();
+}
+
+static void log_sysinfo(void)
+{
+ struct rx_meas_stat *meas = &ms->meas;
+ struct gsm48_sysinfo *s = &sysinfo;
+ int8_t rxlev;
+ char ta_str[32] = "";
+
+ if (log_si.ta != 0xff)
+ sprintf(ta_str, " TA=%d", log_si.ta);
+
+ //LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n",
+ // arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc),
+ // gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str);
+
+ LOGFILE("[SysInfo]\n");
+ LOGFILE("country %s\n", gsm_get_mcc(s->mcc))
+ LOGFILE("provider %s\n", gsm_get_mnc(s->mcc, s->mnc))
+ LOGFILE("arfcn %d\n", s->arfcn);
+ //log_time();
+ //log_gps();
+ //LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7);
+ rxlev = meas->rxlev / meas->frames - 110;
+ LOGFILE("rxlev %d\n", rxlev);
+ //if (s->si1)
+ // log_frame("si1", s->si1_msg);
+ if (s->si2)
+ log_frame("si2", s->si2_msg);
+ if (s->si2bis)
+ log_frame("si2bis", s->si2b_msg);
+ if (s->si2ter)
+ log_frame("si2ter", s->si2t_msg);
+ //if (s->si3)
+ // log_frame("si3", s->si3_msg);
+ //if (s->si4)
+ // log_frame("si4", s->si4_msg);
+ //if (log_si.ta != 0xff)
+ // LOGFILE("ta %d\n", log_si.ta);
+
+ LOGFILE("[EndInfo]\n");
+ LOGFILE("\n");
+ LOGFLUSH();
+}
+
+static void timeout_cb(void *arg)
+{
+ switch (state) {
+ case SCAN_STATE_READ:
+ LOGP(DRR, LOGL_INFO, "Timeout reading BCCH\n");
+ start_sync();
+ break;
+ case SCAN_STATE_RACH:
+ LOGP(DRR, LOGL_INFO, "Timeout on RACH\n");
+ rach_count++;
+ start_rach();
+ break;
+ }
+}
+
+static void stop_timer(void)
+{
+ if (osmo_timer_pending(&timer))
+ osmo_timer_del(&timer);
+}
+
+static void start_timer(int sec, int micro)
+{
+ stop_timer();
+ timer.cb = timeout_cb;
+ timer.data = ms;
+ osmo_timer_schedule(&timer, sec, micro);
+}
+
+static void start_rach(void)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+ uint8_t chan_req_val, chan_req_mask;
+ struct msgb *nmsg;
+ struct abis_rsl_cchan_hdr *ncch;
+
+ if (rach_count == RACH_MAX) {
+ log_sysinfo();
+ start_sync();
+ return;
+ }
+
+ state = SCAN_STATE_RACH;
+
+ if (s->neci) {
+ chan_req_mask = 0x0f;
+ chan_req_val = 0x01;
+ LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
+ "(OTHER with NECI)\n", chan_req_val);
+ } else {
+ chan_req_mask = 0x1f;
+ chan_req_val = 0xe0;
+ LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER no NECI)\n",
+ chan_req_val);
+ }
+
+ rach_ref.valid = 0;
+ rach_ref.cr = random();
+ rach_ref.cr &= chan_req_mask;
+ rach_ref.cr |= chan_req_val;
+
+ nmsg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
+ RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
+ if (!nmsg)
+ return;
+ nmsg->l2h = nmsg->data;
+ ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
+ + 4 + 2 + 2);
+ rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
+ ncch->chan_nr = RSL_CHAN_RACH;
+ ncch->data[0] = RSL_IE_REQ_REFERENCE;
+ ncch->data[1] = rach_ref.cr;
+ ncch->data[2] = (s->ccch_conf == 1) << 7;
+ ncch->data[3] = 0;
+ ncch->data[4] = RSL_IE_ACCESS_DELAY;
+ ncch->data[5] = 0; /* no delay */
+ ncch->data[6] = RSL_IE_MS_POWER;
+ ncch->data[7] = 0; /* full power */
+
+ start_timer(RACH_WAIT);
+
+ lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
+}
+
+static void start_sync(void)
+{
+ int rxlev = -128;
+ int i, dist = 0;
+ char dist_str[32] = "";
+
+ arfcn = 0xffff;
+ for (i = 0; i <= 1023; i++) {
+ if ((pm[i].flags & INFO_FLG_PM)
+ && !(pm[i].flags & INFO_FLG_SYNC)) {
+ if (pm[i].rxlev > rxlev) {
+ rxlev = pm[i].rxlev;
+ arfcn = i;
+ }
+ }
+ }
+ /* if GPS becomes valid, like after exitting a tunnel */
+ if (!pm_gps_valid && g.valid) {
+ pm_gps_valid = 1;
+ geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z, g.longitude,
+ g.latitude);
+ }
+ if (pm_gps_valid && g.valid) {
+ double x, y, z;
+
+ geo2space(&x, &y, &z, g.longitude, g.latitude);
+ dist = distinspace(pm_gps_x, pm_gps_y, pm_gps_z, x, y, z);
+ sprintf(dist_str, " dist %d", (int)dist);
+ }
+ if (dist > MAX_DIST || arfcn == 0xffff || rxlev < min_rxlev) {
+ memset(pm, 0, sizeof(pm));
+ pm_index = 0;
+ sync_count = 0;
+ start_pm();
+ return;
+ }
+ pm[arfcn].flags |= INFO_FLG_SYNC;
+ //HACK: no use for us right now
+ LOGP(DSUM, LOGL_INFO, "Sync ARFCN %d (rxlev %d, %d syncs "
+ "left)%s\n", arfcn, pm[arfcn].rxlev, sync_count--, dist_str);
+ memset(&sysinfo, 0, sizeof(sysinfo));
+ sysinfo.arfcn = arfcn;
+ state = SCAN_STATE_SYNC;
+ l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
+ l1ctl_tx_fbsb_req(ms, arfcn, L1CTL_FBSB_F_FB01SB, 100, 0,
+ CCCH_MODE_NONE);
+}
+
+static void start_pm(void)
+{
+ uint16_t from, to;
+
+ state = SCAN_STATE_PM;
+ from = band_range[pm_index][0];
+ to = band_range[pm_index][1];
+
+ if (from == 0 && to == 0) {
+ LOGP(DSUM, LOGL_INFO, "Measurement done\n");
+ pm_gps_valid = g.enable && g.valid;
+ if (pm_gps_valid)
+ geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z,
+ g.longitude, g.latitude);
+ log_pm();
+ start_sync();
+ return;
+ }
+ LOGP(DSUM, LOGL_INFO, "Measure from %d to %d\n", from, to);
+ l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
+ l1ctl_tx_pm_req_range(ms, from, to);
+}
+
+static int signal_cb(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
+{
+ struct osmobb_meas_res *mr;
+ struct osmobb_fbsb_res *fr;
+ uint16_t index;
+
+ if (subsys != SS_L1CTL)
+ return 0;
+
+ switch (signal) {
+ case S_L1CTL_PM_RES:
+ mr = signal_data;
+ index = mr->band_arfcn & 0x3ff;
+ pm[index].flags |= INFO_FLG_PM;
+ pm[index].rxlev = mr->rx_lev - 110;
+ if (pm[index].rxlev >= min_rxlev)
+ sync_count++;
+// printf("rxlev %d = %d (sync_count %d)\n", index, pm[index].rxlev, sync_count);
+ break;
+ case S_L1CTL_PM_DONE:
+ pm_index++;
+ start_pm();
+ break;
+ case S_L1CTL_FBSB_RESP:
+ fr = signal_data;
+ sysinfo.bsic = fr->bsic;
+ state = SCAN_STATE_READ;
+ memset(&ms->meas, 0, sizeof(ms->meas));
+ memset(&log_si, 0, sizeof(log_si));
+ log_si.flags |= INFO_FLG_SYNC;
+ log_si.ta = 0xff; /* invalid */
+ start_timer(READ_WAIT);
+ LOGP(DRR, LOGL_INFO, "Synchronized, start reading\n");
+ break;
+ case S_L1CTL_FBSB_ERR:
+ LOGP(DRR, LOGL_INFO, "Sync failed\n");
+ start_sync();
+ break;
+ case S_L1CTL_RESET:
+ if (started)
+ break;
+ started = 1;
+ memset(pm, 0, sizeof(pm));
+ pm_index = 0;
+ sync_count = 0;
+ start_pm();
+ }
+ return 0;
+}
+
+static int ta_result(uint8_t ta)
+{
+ stop_timer();
+
+ if (ta == 0xff)
+ LOGP(DSUM, LOGL_INFO, "Got assignment reject\n");
+ else {
+ LOGP(DSUM, LOGL_DEBUG, "Got assignment TA = %d\n", ta);
+ log_si.ta = ta;
+ }
+
+ log_sysinfo();
+ start_sync();
+
+ return 0;
+}
+
+/* match request reference agains request */
+static int match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
+{
+ uint8_t ia_t1, ia_t2, ia_t3;
+
+ /* filter confirmed RACH requests only */
+ if (rach_ref.valid && ref->ra == rach_ref.cr) {
+ ia_t1 = ref->t1;
+ ia_t2 = ref->t2;
+ ia_t3 = (ref->t3_high << 3) | ref->t3_low;
+ if (ia_t1 == rach_ref.t1 && ia_t2 == rach_ref.t2
+ && ia_t3 == rach_ref.t3) {
+ LOGP(DRR, LOGL_INFO, "request %02x matches "
+ "(fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2,
+ ia_t3);
+ return 1;
+ } else
+ LOGP(DRR, LOGL_INFO, "request %02x matches but not "
+ "frame number (IMM.ASS fn=%d,%d,%d != RACH "
+ "fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2, ia_t3,
+ rach_ref.t1, rach_ref.t2, rach_ref.t3);
+ }
+
+ return 0;
+}
+
+/* 9.1.18 IMMEDIATE ASSIGNMENT is received */
+static int imm_ass(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_imm_ass *ia = msgb_l3(msg);
+
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT:\n");
+
+ if (state != SCAN_STATE_RACH) {
+ LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
+ return 0;
+ }
+
+ /* request ref */
+ if (match_ra(ms, &ia->req_ref)) {
+ return ta_result(ia->timing_advance);
+ }
+ LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
+
+ return 0;
+}
+
+/* 9.1.19 IMMEDIATE ASSIGNMENT EXTENDED is received */
+static int imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
+
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT EXTENDED:\n");
+
+ if (state != SCAN_STATE_RACH) {
+ LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
+ return 0;
+ }
+
+ /* request ref 1 */
+ if (match_ra(ms, &ia->req_ref1)) {
+ return ta_result(ia->timing_advance1);
+ }
+ /* request ref 2 */
+ if (match_ra(ms, &ia->req_ref2)) {
+ return ta_result(ia->timing_advance2);
+ }
+ LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
+
+ return 0;
+}
+
+/* 9.1.20 IMMEDIATE ASSIGNMENT REJECT is received */
+static int imm_ass_rej(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
+ int i;
+ struct gsm48_req_ref *req_ref;
+
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT:\n");
+
+ if (state != SCAN_STATE_RACH) {
+ LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
+ return 0;
+ }
+
+ for (i = 0; i < 4; i++) {
+ /* request reference */
+ req_ref = (struct gsm48_req_ref *)
+ (((uint8_t *)&ia->req_ref1) + i * 4);
+ LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT "
+ "(ref 0x%02x)\n", req_ref->ra);
+ if (match_ra(ms, req_ref)) {
+ return ta_result(0xff);
+ }
+ }
+
+ return 0;
+}
+
+/* receive CCCH at RR layer */
+static int pch_agch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
+
+ switch (sih->system_information) {
+ case GSM48_MT_RR_PAG_REQ_1:
+ case GSM48_MT_RR_PAG_REQ_2:
+ case GSM48_MT_RR_PAG_REQ_3:
+ return 0;
+ case GSM48_MT_RR_IMM_ASS:
+ return imm_ass(ms, msg);
+ case GSM48_MT_RR_IMM_ASS_EXT:
+ return imm_ass_ext(ms, msg);
+ case GSM48_MT_RR_IMM_ASS_REJ:
+ return imm_ass_rej(ms, msg);
+ default:
+ return -EINVAL;
+ }
+}
+
+/* check if sysinfo is complete, change to RACH state */
+static int new_sysinfo(void)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+
+ /* restart timer */
+ start_timer(READ_WAIT);
+
+ /* mandatory */
+ if (!s->si1 || !s->si2 || !s->si3 || !s->si4) {
+ LOGP(DRR, LOGL_INFO, "not all mandatory SI received\n");
+ return 0;
+ }
+
+ /* extended band */
+ if (s->nb_ext_ind_si2 && !s->si2bis) {
+ LOGP(DRR, LOGL_INFO, "extended ba, but si2bis not received\n");
+ return 0;
+ }
+
+ /* 2ter */
+ if (s->si2ter_ind && !s->si2ter) {
+ LOGP(DRR, LOGL_INFO, "si2ter_ind, but si2ter not received\n");
+ return 0;
+ }
+
+ LOGP(DRR, LOGL_INFO, "Sysinfo complete\n");
+
+ stop_timer();
+
+ rach_count = 0;
+ start_rach();
+
+ return 0;
+}
+
+/* receive BCCH at RR layer */
+static int bcch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
+ uint8_t ccch_mode;
+
+ if (msgb_l3len(msg) != 23) {
+ LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n");
+ return -EINVAL;
+ }
+ switch (sih->system_information) {
+ case GSM48_MT_RR_SYSINFO_1:
+ if (!memcmp(sih, s->si1_msg, sizeof(s->si1_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
+ gsm48_decode_sysinfo1(s,
+ (struct gsm48_system_information_type_1 *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_2:
+ if (!memcmp(sih, s->si2_msg, sizeof(s->si2_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
+ gsm48_decode_sysinfo2(s,
+ (struct gsm48_system_information_type_2 *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_2bis:
+ if (!memcmp(sih, s->si2b_msg, sizeof(s->si2b_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
+ gsm48_decode_sysinfo2bis(s,
+ (struct gsm48_system_information_type_2bis *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_2ter:
+ if (!memcmp(sih, s->si2t_msg, sizeof(s->si2t_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
+ gsm48_decode_sysinfo2ter(s,
+ (struct gsm48_system_information_type_2ter *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_3:
+ if (!memcmp(sih, s->si3_msg, sizeof(s->si3_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 3\n");
+ gsm48_decode_sysinfo3(s,
+ (struct gsm48_system_information_type_3 *) sih,
+ msgb_l3len(msg));
+ ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
+ CCCH_MODE_NON_COMBINED;
+ LOGP(DRR, LOGL_INFO, "Changing CCCH_MODE to %d\n", ccch_mode);
+ l1ctl_tx_ccch_mode_req(ms, ccch_mode);
+ return new_sysinfo();
+ case GSM48_MT_RR_SYSINFO_4:
+ if (!memcmp(sih, s->si4_msg, sizeof(s->si4_msg)))
+ return 0;
+ LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
+ gsm48_decode_sysinfo4(s,
+ (struct gsm48_system_information_type_4 *) sih,
+ msgb_l3len(msg));
+ return new_sysinfo();
+ default:
+ return -EINVAL;
+ }
+}
+
+static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ struct tlv_parsed tv;
+ uint8_t ch_type, ch_subch, ch_ts;
+
+ DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
+ rllh->chan_nr, rllh->link_id);
+
+ rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
+ if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
+ DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
+ return -EIO;
+ }
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
+
+ if (state != SCAN_STATE_READ && state != SCAN_STATE_RACH) {
+ return -EINVAL;
+ }
+
+ rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
+ switch (ch_type) {
+ case RSL_CHAN_PCH_AGCH:
+ return pch_agch(ms, msg);
+ case RSL_CHAN_BCCH:
+ return bcch(ms, msg);
+#if 0
+ case RSL_CHAN_Bm_ACCHs:
+ case RSL_CHAN_Lm_ACCHs:
+ case RSL_CHAN_SDCCH4_ACCH:
+ case RSL_CHAN_SDCCH8_ACCH:
+ return rx_acch(ms, msg);
+#endif
+ default:
+ LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
+ rllh->chan_nr);
+ return -EINVAL;
+ }
+}
+
+static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ int msg_type = rllh->c.msg_type;
+
+ if (msg_type == RSL_MT_UNIT_DATA_IND) {
+ unit_data_ind(ms, msg);
+ } else
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
+
+ msgb_free(msg);
+
+ return 0;
+}
+
+int chan_conf(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
+ struct gsm48_req_ref *ref = (struct gsm48_req_ref *) (ch->data + 1);
+
+ if (msgb_l2len(msg) < sizeof(*ch) + sizeof(*ref)) {
+ LOGP(DRR, LOGL_ERROR, "CHAN_CNF too slort\n");
+ return -EINVAL;
+ }
+
+ rach_ref.valid = 1;
+ rach_ref.t1 = ref->t1;
+ rach_ref.t2 = ref->t2;
+ rach_ref.t3 = ref->t3_low | (ref->t3_high << 3);
+
+ return 0;
+}
+
+static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
+ int msg_type = ch->c.msg_type;
+ int rc;
+
+ LOGP(DRSL, LOGL_INFO, "Received '%s' from layer1\n",
+ rsl_msg_name(msg_type));
+
+ if (state == SCAN_STATE_RACH && msg_type == RSL_MT_CHAN_CONF) {
+ rc = chan_conf(ms, msg);
+ msgb_free(msg);
+ return rc;
+ }
+
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
+ msgb_free(msg);
+ return 0;
+}
+
+static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
+{
+ struct osmocom_ms *ms = l3ctx;
+ struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
+ int rc = 0;
+
+ switch (rslh->msg_discr & 0xfe) {
+ case ABIS_RSL_MDISC_RLL:
+ rc = rcv_rll(ms, msg);
+ break;
+ case ABIS_RSL_MDISC_COM_CHAN:
+ rc = rcv_cch(ms, msg);
+ break;
+ default:
+ LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
+ rslh->msg_discr);
+ msgb_free(msg);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+int scan_init(struct osmocom_ms *_ms)
+{
+ ms = _ms;
+ osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
+ memset(&timer, 0, sizeof(timer));
+ lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
+ g.enable = 1;
+ osmo_gps_init();
+ if (osmo_gps_open())
+ g.enable = 0;
+
+ if (!strcmp(logname, "-"))
+ logfp = stdout;
+ else
+ logfp = fopen(logname, "a");
+ if (!logfp) {
+ fprintf(stderr, "Failed to open logfile '%s'\n", logname);
+ scan_exit();
+ return -errno;
+ }
+ LOGP(DSUM, LOGL_INFO, "Scanner initialized\n");
+
+ return 0;
+}
+
+int scan_exit(void)
+{
+ LOGP(DSUM, LOGL_INFO, "Scanner exit\n");
+ if (g.valid)
+ osmo_gps_close();
+ if (logfp)
+ fclose(logfp);
+ osmo_signal_unregister_handler(SS_L1CTL, &signal_cb, NULL);
+ stop_timer();
+
+ return 0;
+}
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
index 627f3fd..77b19d8 100644
--- a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
Binary files differ
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/6.tree b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/6.tree
new file mode 100644
index 0000000..19535d3
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.root/6.tree
Binary files differ
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
index a98b0ee..2437e0c 100644
--- a/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
Binary files differ
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/Src/eclipse/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
index 94ae83d..33601d8 100644
--- a/Src/eclipse/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
@@ -1,7 +1,7 @@
-#Tue Feb 28 12:14:41 CET 2012
+#Tue Feb 28 12:46:40 CET 2012
eclipse.preferences.version=1
TASKS_FILTERS_MIGRATE=true
tipsAndTricks=true
-platformState=1330425960816
+platformState=1330428858162
quickStart=true
PROBLEMS_FILTERS_MIGRATE=true
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.history b/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.history
new file mode 100644
index 0000000..9cf3766
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.history
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<session version="1.0">&#x0A;<refactoring comment="Delete 2 resources" deleteContents="false" description="Delete 2 resources" element1="/CatcherLib" element2="/PyCatcher" flags="7" id="org.eclipse.ltk.core.refactoring.delete.resources" resources="2" stamp="1330426031197"/>&#x0A;<refactoring comment="Delete resource &apos;CatcherDriver&apos;" deleteContents="false" description="Delete resource &apos;CatcherDriver&apos;" element1="/CatcherDriver" flags="7" id="org.eclipse.ltk.core.refactoring.delete.resources" resources="1" stamp="1330429654807"/>
+</session> \ No newline at end of file
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.index b/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.index
new file mode 100644
index 0000000..4a8774b
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/2/9/refactorings.index
@@ -0,0 +1,2 @@
+1330426031197 Delete 2 resources
+1330429654807 Delete resource 'CatcherDriver'
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml b/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml
new file mode 100644
index 0000000..27eb404
--- /dev/null
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section name="Workbench">
+ <section name="RefactoringWizard.preview">
+ <item value="400" key="height"/>
+ <item value="600" key="width"/>
+ </section>
+</section>
diff --git a/Src/eclipse/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/Src/eclipse/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml
index 50a2f47..8a7667a 100644
--- a/Src/eclipse/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml
+++ b/Src/eclipse/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<workbench progressCount="4" version="2.0">
+<workbench progressCount="17" version="2.0">
<workbenchAdvisor/>
<window height="1081" maximized="true" width="1922" x="1280" y="0">
<fastViewData fastViewLocation="1024"/>
@@ -41,7 +41,7 @@
</editorArea>
<editor activePart="true" focus="true" id="org.eclipse.cdt.ui.editor.CEditor" name="catcher.c" partName="catcher.c" path="/home/tom/Documents/imsi-catcher-detection/Src/osmolib/src/host/layer23/src/misc/catcher.c" title="catcher.c" tooltip="CatcherDriver/host/layer23/src/misc/catcher.c" workbook="DefaultEditorWorkbook">
<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/CatcherDriver/host/layer23/src/misc/catcher.c"/>
-<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="4332" selectionTopPixel="3084"/>
+<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="14686" selectionTopPixel="10657"/>
</editor>
<editor id="org.eclipse.cdt.ui.editor.CEditor" name="sysinfo.h" partName="sysinfo.h" path="/home/tom/Documents/imsi-catcher-detection/Src/osmolib/src/host/layer23/include/osmocom/bb/common/sysinfo.h" title="sysinfo.h" tooltip="CatcherDriver/host/layer23/include/osmocom/bb/common/sysinfo.h" workbook="DefaultEditorWorkbook">
<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/CatcherDriver/host/layer23/include/osmocom/bb/common/sysinfo.h"/>
@@ -92,8 +92,8 @@
<view id="org.eclipse.ui.views.ResourceNavigator" partName="Navigator">
<viewState LINK_NAVIGATOR_TO_EDITOR="0" sorter="1">
<filters>
-<filter element=".*" isEnabled="false"/>
<filter element="*.class" isEnabled="true"/>
+<filter element=".*" isEnabled="false"/>
</filters>
<expanded>
<element path="/CatcherDriver"/>
diff --git a/Src/osmolib/include/l1ctl_proto.h b/Src/osmolib/include/l1ctl_proto.h
index c1220d6..4b9540e 100644
--- a/Src/osmolib/include/l1ctl_proto.h
+++ b/Src/osmolib/include/l1ctl_proto.h
@@ -283,12 +283,15 @@ struct l1ctl_neigh_pm_req {
uint8_t n;
uint8_t padding[1];
uint16_t band_arfcn[64];
+ uint8_t tn[64];
} __attribute__((packed));
/* neighbour cell measurement results */
struct l1ctl_neigh_pm_ind {
uint16_t band_arfcn;
uint8_t pm[2];
+ uint8_t tn;
+ uint8_t padding;
} __attribute__((packed));
/* traffic data to network */
diff --git a/Src/osmolib/src/.cproject b/Src/osmolib/src/.cproject
new file mode 100644
index 0000000..f23e408
--- /dev/null
+++ b/Src/osmolib/src/.cproject
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+<storageModule moduleId="org.eclipse.cdt.core.settings">
+<cconfiguration id="0.1568089738">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1568089738" moduleId="org.eclipse.cdt.core.settings" name="Default">
+<externalSettings/>
+<extensions>
+<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactName="catcher" buildProperties="" description="" id="0.1568089738" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
+<folderInfo id="0.1568089738." name="/" resourcePath="">
+<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.356512209" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
+<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.356512209.15336239" name=""/>
+<builder id="org.eclipse.cdt.build.core.settings.default.builder.1829941210" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1321586476" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
+<tool id="org.eclipse.cdt.build.core.settings.holder.187679752" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
+<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.10655658" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+</tool>
+<tool id="org.eclipse.cdt.build.core.settings.holder.2059651325" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
+<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.2069892859" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+</tool>
+<tool id="org.eclipse.cdt.build.core.settings.holder.7400946" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
+<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1717505204" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+</tool>
+</toolChain>
+</folderInfo>
+</configuration>
+</storageModule>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="0.1568089738">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+</cconfiguration>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<project id="catcher.null.2014221762" name="catcher"/>
+</storageModule>
+</cproject>
diff --git a/Src/osmolib/src/.project b/Src/osmolib/src/.project
new file mode 100644
index 0000000..2b3b054
--- /dev/null
+++ b/Src/osmolib/src/.project
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>catcher</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+ <value>clean</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>true</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+</projectDescription>
diff --git a/Src/osmolib/src/host/calypso_pll/pll.pl b/Src/osmolib/src/host/calypso_pll/pll.pl
index 52c9131..52c9131 100644..100755
--- a/Src/osmolib/src/host/calypso_pll/pll.pl
+++ b/Src/osmolib/src/host/calypso_pll/pll.pl
diff --git a/Src/osmolib/src/host/fb_tools/bdf_to_c.py b/Src/osmolib/src/host/fb_tools/bdf_to_c.py
new file mode 100755
index 0000000..2a3a644
--- /dev/null
+++ b/Src/osmolib/src/host/fb_tools/bdf_to_c.py
@@ -0,0 +1,294 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+'''
+This script converts a bdf-font to a c-source-file containing
+selected glyphs in the format defined by the <fb/font.h> header.
+'''
+
+# (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+#
+# All Rights Reserved
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from optparse import OptionParser
+import sys
+import os
+import string
+
+def unique_name(thisname,existingnames) :
+ # return first of thisname, thisname_1, thisname_2, ...
+ # that does not yet exist in existingnames. This is used
+ # because somethings glyphs with non-unique names exist
+ # in fonts!
+ retname=thisname
+ N=1
+ while retname in existingnames :
+ N=N+1
+ retname='%s_%d'%(thisname,N)
+ return retname
+
+
+# return number N (for a character), optionally including
+# the ascii character
+def ascii_charnum(n) :
+ if n >= 32 and n < 127 :
+ if n != 34 : # """ looks stupid
+ return '(%d, ASCII "%s")'%(n,chr(n))
+ else :
+ return '(%d, ASCII \'%s\')'%(n,chr(n))
+ return '(%d)'%(n)
+
+def is_zeroes(s) :
+ # check if list s consists entirely of "00" strings
+ # (used to detect empty lines in fonts)
+ for x in s :
+ if s != '00' :
+ return False
+ return True
+
+def byte_to_bits(x) :
+ # convert byte x to a string representing the bits #=1, .=0
+ # used for drawing pretty pictures in the comments of the
+ # generated C-file
+ ret = ''
+ for i in range(8) :
+ if x & 1<<(7-i) :
+ ret = ret + '#'
+ else :
+ ret = ret + '.'
+ return ret
+
+class BDF_Font(object) :
+ # this class stores a read-in bdf font
+ def __init__(self,filename) :
+ self.filename = filename
+ self.glyphs = dict()
+ self.enc = dict()
+ self.height = None
+ self.registry = None
+ self.encoding = None
+ self.ascent = 0
+ self.descent = 0
+ self.read_font(filename)
+
+ def add_header(self,data) :
+ #print 'Header data: ',data
+ self.registry = data.get('charset_registry','none')
+ self.encoding = data.get('charset_encoding','unknown')
+ self.ascent = int(data['font_ascent'])
+ self.descent = int(data['font_descent'])
+ bbx = data['fontboundingbox'].split(None,3)
+ self.height = int(bbx[1])
+
+ def add_glyph(self,charname,data,bitmap) :
+ chnum = int(data['encoding'])
+# print 'add_glyph(%s) -> %s'%(charname,ascii_charnum(chnum))
+ self.enc[chnum] = charname
+ self.glyphs[charname] = data
+ self.glyphs[charname]['bitmap']=bitmap
+
+ def read_font(self,filename) :
+ f = file(filename)
+
+ hdr_data = dict()
+ # read in header
+ for l in f :
+ l = l.strip()
+ if l == '' :
+ continue
+ arr = l.split(None,1)
+ if len(arr) > 1 :
+ hdr_data[ arr[0].lower() ] = arr[1]
+ if arr[0].lower() == 'chars' :
+ break
+
+ self.add_header(hdr_data)
+
+ # now read in characters
+ inchar = None
+ data = dict() # store glyph data
+ bitmap = None
+ for l in f :
+ l = l.strip()
+ if l == '' :
+ continue
+
+ # waiting for next glyph
+ if inchar == None :
+ if l.lower() == 'endfont' :
+ break # end of font :-)
+ arr = l.split(None,1)
+ if len(arr) < 2 and \
+ arr[0].lower() != 'STARTCHAR' :
+ print >>sys.stderr,'Not start of glyph: %s'%(l)
+ continue
+ inchar = unique_name(arr[1],self.glyphs)
+ continue
+
+ # ENDCHAR always ends the glyph
+ if l.lower() == 'endchar' :
+ self.add_glyph(inchar,data,bitmap)
+ inchar = None
+ bitmap = None
+ data = dict()
+ continue
+
+ # in bitmap
+ if bitmap != None :
+ bitmap.append(l)
+ continue
+
+ # else: metadata for this glyph
+ arr = l.split(None,1)
+
+ if arr[0].lower() == 'bitmap' :
+ bitmap = list() # start collecting pixels
+ continue
+
+ if len(arr) < 2 :
+ print >>sys.stderr,'Bad line in font: %s'%(l)
+ continue
+ data[arr[0].lower()] = arr[1]
+
+if __name__ == '__main__' :
+ P = OptionParser(usage='%prog [options] bdf-file')
+ P.add_option('-o','--out',action='store', dest='out', default=None,
+ metavar='FILE',help='write .c-code representing font to FILE')
+ P.add_option('-b','--base',action='store',dest='base',default=None,
+ metavar='base_symbol',help='prefix for all generated symbols')
+ P.add_option('-f','--firstchar',action='store',dest='firstchar',type="int",
+ metavar='N',default=None,help='numeric value of first char')
+ P.add_option('-l','--lastchar',action='store',dest='lastchar',type="int",
+ metavar='N',default=None,help='numeric value of last char')
+
+ opts,args = P.parse_args()
+
+ if len(args) != 1 :
+ P.error('Please specify (exactly one) bdf input file.')
+
+ font = BDF_Font(args[0])
+
+ if opts.firstchar == None :
+ opts.firstchar = min(font.enc)
+ print 'First character in font: %d, %s'%(opts.firstchar,
+ font.enc[opts.firstchar])
+
+ if opts.lastchar == None :
+ opts.lastchar = max(font.enc)
+ print 'Last character in font: %d, %s'%(opts.lastchar,
+ font.enc[opts.lastchar])
+
+ if opts.base == None :
+ opts.base = 'font_'+os.path.basename(args[0])
+ if opts.base[-4:] == '.bdf' :
+ opts.base = opts.base[:-4]
+ print >>sys.stderr,'Guessing symbol prefix to be %s.'%(opts.base)
+
+ if opts.out == None :
+ opts.out = os.path.basename(args[0])
+ if opts.out[-4:] == '.bdf' :
+ opts.out = opts.out[:-4]
+ opts.out = opts.out + '.c'
+ print >>sys.stderr,'Guessing output filename to be %s.'%(opts.out)
+
+ if os.path.exists(opts.out) :
+ print >>sys.stderr,'Will *NOT* overwrite existing file when guessing output!'
+ sys.exit(1)
+
+ of = file(opts.out,'w')
+
+ print >>of,'#include <fb/font.h>'
+ print >>of,'/* file autogenerated by %s */'%(sys.argv[0])
+
+ offsets = list()
+ glyphnames = list()
+
+ print >>of,'static const uint8_t %s_data[] = {'%(opts.base)
+
+ pos = 0
+
+ # output font data, build up per-character information
+
+ for i in range(opts.firstchar,opts.lastchar+1) :
+ if not i in font.enc :
+ offsets.append(0xffff)
+ glyphnames.append('(no glyph)')
+ continue
+
+ charname = font.enc[i]
+ glyphnames.append('%s %s'%(charname,ascii_charnum(i)))
+ offsets.append(pos)
+ glyph = font.glyphs[charname]
+ bbx = map(int,glyph['bbx'].split(None,3))
+ bitmap = glyph['bitmap']
+
+ if bbx[1] != len(bitmap) :
+ print >>sys.stderr,'ERROR: glyph',charname,'has wrong number of lines of data!'
+ print >>sys.stderr,' want: ',bbx[1],'but have',len(bitmap)
+ sys.exit(1)
+
+ removedrows = 0
+
+ while len(bitmap) > 1 and is_zeroes(bitmap[0]) :
+ removedrows = removedrows + 1
+ bbx[1] = bbx[1] - 1 # decrease height
+ bitmap = bitmap[1:]
+
+ while len(bitmap) > 1 and is_zeroes(bitmap[-1]) :
+ removedrows = removedrows + 1
+ bbx[1] = bbx[1] - 1 # decrease height
+ bbx[3] = bbx[3] + 1 # increase y0
+ bitmap = bitmap[:-1]
+
+ if removedrows > 0 :
+ print "Glyph %s: removed %d rows."%(charname,removedrows)
+
+ w = int(glyph['dwidth'].split(None,1)[0])
+
+ print >>of,'/* --- new character %s %s starting at offset 0x%04x --- */'%(
+ charname,ascii_charnum(i),pos)
+ print >>of,'\t/*%04x:*/\t%d, %d, %d, %d, %d, /* width and bbox (w,h,x,y) */'%(
+ pos,w,bbx[0],bbx[1],bbx[2],bbx[3])
+
+ pos += 5
+
+ for k,l in enumerate(bitmap) :
+ bytes = [ int(l[i:i+2],16) for i in range(0,len(l),2) ]
+ if len(bytes) != (bbx[0]+7)/8 :
+ print >>sys.stderr,'ERROR: glyph',charname,'has wrong # of bytes'
+ print >>sys.stderr,' per line. Want',(bbx[0]+7)/8,'have',len(bytes)
+ sys.exit(1)
+ cdata = ','.join([ '0x%02x'%v for v in bytes ])
+ comment = ''.join([ byte_to_bits(b) for b in bytes ])
+ print >>of,'\t/*%04x:*/\t'%(pos)+cdata+', /* '+comment+' */'
+ pos += len(bytes)
+
+ print >>of,"};"
+
+ x = ',\n\t'.join(['0x%04x /* %s */'%(w,n) for w,n in zip(offsets,glyphnames)])
+ print >>of,'static const uint16_t %s_offsets[] = {\n\t%s\n};'%(opts.base,x)
+
+ height = font.ascent + font.descent
+
+ print >>of,'const struct fb_font %s = {'%(opts.base)
+ print >>of,'\t.height = %d,'%(height)
+ print >>of,'\t.ascent = %d,'%(font.ascent)
+ print >>of,'\t.firstchar = %d, /* %s */'%(opts.firstchar,font.enc.get(opts.firstchar,"?"))
+ print >>of,'\t.lastchar = %d, /* %s */'%(opts.lastchar,font.enc.get(opts.lastchar,"?"))
+ print >>of,'\t.chardata = %s_data,'%(opts.base)
+ print >>of,'\t.charoffs = %s_offsets,'%(opts.base)
+ print >>of,'};'
diff --git a/Src/osmolib/src/host/gsmmap/git-version-gen b/Src/osmolib/src/host/gsmmap/git-version-gen
index 652fac6..652fac6 100644..100755
--- a/Src/osmolib/src/host/gsmmap/git-version-gen
+++ b/Src/osmolib/src/host/gsmmap/git-version-gen
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/Makefile.am b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/Makefile.am
index 26e63cf..945c73d 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/Makefile.am
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/Makefile.am
@@ -1,2 +1,2 @@
-noinst_HEADERS = l1ctl.h l1l2_interface.h l23_app.h lapdm.h logging.h \
+noinst_HEADERS = l1ctl.h l1l2_interface.h l23_app.h logging.h \
networks.h gps.h sysinfo.h osmocom_data.h
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/logging.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/logging.h
index 554b767..3efa57a 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/logging.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/logging.h
@@ -12,11 +12,11 @@ enum {
DNB,
DMM,
DCC,
+ DSS,
DSMS,
DMNCC,
DMEAS,
DPAG,
- DLAPDM,
DL1C,
DSAP,
DSUM,
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/networks.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/networks.h
index e681216..d34f316 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/networks.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/networks.h
@@ -10,7 +10,7 @@ struct gsm_networks {
};
int gsm_match_mcc(uint16_t mcc, char *imsi);
-int gsm_match_mnc(uint16_t mcc, uint8_t mnc, char *imsi);
+int gsm_match_mnc(uint16_t mcc, uint16_t mnc, char *imsi);
const char *gsm_print_mcc(uint16_t mcc);
const char *gsm_print_mnc(uint16_t mcc);
const char *gsm_get_mcc(uint16_t mcc);
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
index 8f15007..ab7c250 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
@@ -11,7 +11,7 @@ struct osmocom_ms;
#include <osmocom/bb/mobile/support.h>
#include <osmocom/bb/mobile/settings.h>
#include <osmocom/bb/mobile/subscriber.h>
-#include <osmocom/bb/common/lapdm.h>
+#include <osmocom/gsm/lapdm.h>
#include <osmocom/bb/common/sap_interface.h>
#include <osmocom/bb/mobile/gsm48_rr.h>
#include <osmocom/bb/common/sysinfo.h>
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/sim.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/sim.h
index a676b92..95d2147 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/common/sim.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/common/sim.h
@@ -266,6 +266,16 @@ struct gsm1111_ef_adn {
uint8_t ext_id;
} __attribute__ ((packed));
+/* Section 10.5.6 */
+struct gsm1111_ef_smsp {
+ uint8_t par_ind;
+ uint8_t tp_da[12];
+ uint8_t ts_sca[12];
+ uint8_t tp_proto;
+ uint8_t tp_dcs;
+ uint8_t tp_vp;
+} __attribute__ ((packed));
+
int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg);
int gsm_sim_init(struct osmocom_ms *ms);
int gsm_sim_exit(struct osmocom_ms *ms);
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/Makefile.am b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
index 65b7ce7..b58b952 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
@@ -1,2 +1,3 @@
-noinst_HEADERS = gsm322.h gsm48_cc.h gsm48_mm.h gsm48_rr.h mncc.h settings.h \
- subscriber.h support.h transaction.h vty.h mncc_sock.h
+noinst_HEADERS = gsm322.h gsm480_ss.h gsm411_sms.h gsm48_cc.h gsm48_mm.h \
+ gsm48_rr.h mncc.h settings.h subscriber.h support.h \
+ transaction.h vty.h mncc_sock.h
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h
new file mode 100644
index 0000000..d14e6db
--- /dev/null
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm411_sms.h
@@ -0,0 +1,33 @@
+#ifndef _GSM411_SMS_H
+#define _GSM411_SMS_H
+
+#define SMS_HDR_SIZE 128
+#define SMS_TEXT_SIZE 256
+
+struct gsm_sms {
+ unsigned long validity_minutes;
+ uint8_t reply_path_req;
+ uint8_t status_rep_req;
+ uint8_t ud_hdr_ind;
+ uint8_t protocol_id;
+ uint8_t data_coding_scheme;
+ uint8_t msg_ref;
+ char address[20+1]; /* DA LV is 12 bytes max, i.e. 10 bytes
+ * BCD == 20 bytes string */
+ time_t time;
+ uint8_t user_data_len;
+ uint8_t user_data[SMS_TEXT_SIZE];
+
+ char text[SMS_TEXT_SIZE];
+};
+
+int gsm411_sms_init(struct osmocom_ms *ms);
+int gsm411_sms_exit(struct osmocom_ms *ms);
+struct gsm_sms *sms_alloc(void);
+void sms_free(struct gsm_sms *sms);
+struct gsm_sms *sms_from_text(const char *receiver, int dcs, const char *text);
+int gsm411_rcv_sms(struct osmocom_ms *ms, struct msgb *msg);
+int sms_send(struct osmocom_ms *ms, const char *sms_sca, const char *number,
+ const char *text);
+
+#endif /* _GSM411_SMS_H */
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm480_ss.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm480_ss.h
new file mode 100644
index 0000000..ecd778e
--- /dev/null
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm480_ss.h
@@ -0,0 +1,9 @@
+#ifndef _GSM480_SS_H
+#define _GSM480_SS_H
+
+int gsm480_ss_init(struct osmocom_ms *ms);
+int gsm480_ss_exit(struct osmocom_ms *ms);
+int gsm480_rcv_ss(struct osmocom_ms *ms, struct msgb *msg);
+int ss_send(struct osmocom_ms *ms, const char *code, int new_trans);
+
+#endif /* _GSM480_SS_H */
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
index afdcf02..fb62aae 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
@@ -58,6 +58,7 @@ struct gsm48_mmxx_hdr {
int msg_type; /* MMxx_* primitive */
uint32_t ref; /* reference to transaction */
uint32_t transaction_id; /* transaction identifier */
+ uint8_t sapi; /* sapi */
uint8_t emergency; /* emergency type of call */
uint8_t cause; /* cause used for release */
};
@@ -193,6 +194,9 @@ struct gsm48_mmlayer {
uint8_t est_cause; /* cause of establishment msg */
int mr_substate; /* rem most recent substate */
uint8_t power_off_idle; /* waits for IDLE before po */
+
+ /* sapi 3 */
+ int sapi3_link;
};
/* MM connection entry */
@@ -204,6 +208,7 @@ struct gsm48_mm_conn {
uint32_t ref; /* reference to trans */
uint8_t protocol;
uint8_t transaction_id;
+ uint8_t sapi;
int state;
};
@@ -221,7 +226,7 @@ int gsm48_mmr_dequeue(struct osmocom_ms *ms);
int gsm48_mmevent_dequeue(struct osmocom_ms *ms);
int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg);
struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
- uint8_t transaction_id);
+ uint8_t transaction_id, uint8_t sapi);
const char *get_mmr_name(int value);
const char *get_mmxx_name(int value);
extern const char *gsm48_mm_state_names[];
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
index 1af09f4..b7280fb 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
@@ -54,6 +54,7 @@
/* GSM 04.08 RR-SAP header */
struct gsm48_rr_hdr {
uint32_t msg_type; /* RR-* primitive */
+ uint8_t sapi;
uint8_t cause;
};
@@ -63,6 +64,12 @@ struct gsm48_rr_hdr {
#define GSM48_RR_ST_DEDICATED 2
#define GSM48_RR_ST_REL_PEND 3
+/* special states for SAPI 3 link */
+#define GSM48_RR_SAPI3ST_IDLE 0
+#define GSM48_RR_SAPI3ST_WAIT_EST 1
+#define GSM48_RR_SAPI3ST_ESTAB 2
+#define GSM48_RR_SAPI3ST_WAIT_REL 3
+
/* modify state */
#define GSM48_RR_MOD_NONE 0
#define GSM48_RR_MOD_IMM_ASS 1
@@ -79,7 +86,6 @@ struct gsm48_rr_cd {
uint8_t maio;
uint8_t hsn;
uint8_t chan_nr; /* type, slot, sub slot */
- uint8_t link_id;
uint8_t ind_tx_power; /* last indicated power */
uint8_t ind_ta; /* last indicated ta */
uint8_t mob_alloc_lv[9]; /* len + up to 64 bits */
@@ -133,6 +139,7 @@ struct gsm48_rrlayer {
uint8_t rr_est_req;
struct msgb *rr_est_msg;
uint8_t est_cause; /* cause used for establishment */
+ uint8_t paging_mi_type; /* how did we got paged? */
/* channel request states */
uint8_t wait_assign; /* waiting for assignment state */
@@ -175,6 +182,10 @@ struct gsm48_rrlayer {
/* audio flow */
uint8_t audio_mode;
+
+ /* sapi 3 */
+ uint8_t sapi3_state;
+ uint8_t sapi3_link_id;
};
const char *get_rr_name(int value);
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/mncc.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/mncc.h
index 1d7f779..cad1883 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/mncc.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/mncc.h
@@ -130,11 +130,11 @@ struct gsm_call {
struct gsm_mncc {
/* context based information */
- u_int32_t msg_type;
- u_int32_t callref;
+ uint32_t msg_type;
+ uint32_t callref;
/* which fields are present */
- u_int32_t fields;
+ uint32_t fields;
/* data derived informations (MNCC_F_ based) */
struct gsm_mncc_bearer_cap bearer_cap;
@@ -161,12 +161,13 @@ struct gsm_mncc {
int emergency;
char imsi[16];
+ unsigned char lchan_type;
unsigned char lchan_mode;
};
struct gsm_data_frame {
- u_int32_t msg_type;
- u_int32_t callref;
+ uint32_t msg_type;
+ uint32_t callref;
unsigned char data[0];
};
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/settings.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/settings.h
index cd1b800..6d44696 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/settings.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/settings.h
@@ -23,6 +23,9 @@ struct gsm_settings {
int sim_type; /* selects card on power on */
char emergency_imsi[16];
+ /* SMS */
+ char sms_sca[22];
+
/* test card simulator settings */
char test_imsi[16];
uint32_t test_tmsi;
@@ -84,6 +87,7 @@ struct gsm_settings {
/* radio */
uint16_t dsc_max;
+ uint8_t force_rekey;
/* dialing */
struct llist_head abbrev;
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
index cc0cfac..3e50e29 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
@@ -77,6 +77,9 @@ struct gsm_subscriber {
uint32_t sim_handle_query;
uint32_t sim_handle_update;
uint32_t sim_handle_key;
+
+ /* SMS */
+ char sms_sca[22];
};
int gsm_subscr_init(struct osmocom_ms *ms);
@@ -102,6 +105,7 @@ int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
void gsm_subscr_dump(struct gsm_subscriber *subscr,
void (*print)(void *, const char *, ...), void *priv);
char *gsm_check_imsi(const char *imsi);
+int gsm_subscr_get_key_seq(struct osmocom_ms *ms, struct gsm_subscriber *subscr);
#endif /* _SUBSCRIBER_H */
diff --git a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/transaction.h b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/transaction.h
index aa62f46..8c06d5d 100644
--- a/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/transaction.h
+++ b/Src/osmolib/src/host/layer23/include/osmocom/bb/mobile/transaction.h
@@ -2,6 +2,8 @@
#define _TRANSACT_H
#include <osmocom/core/linuxlist.h>
+#include <osmocom/gsm/gsm0411_smc.h>
+#include <osmocom/gsm/gsm0411_smr.h>
/* One transaction */
struct gsm_trans {
@@ -38,18 +40,21 @@ struct gsm_trans {
struct osmo_timer_list timer;
struct gsm_mncc msg; /* stores setup/disconnect/release message */
} cc;
-#if 0
struct {
- uint8_t link_id; /* RSL Link ID to be used for this trans */
- int is_mt; /* is this a MO (0) or MT (1) transfer */
- enum gsm411_cp_state cp_state;
- struct osmo_timer_list cp_timer;
+ /* current supp.serv. state */
+ int state;
+
+ uint8_t invoke_id;
+ struct msgb *msg;
+ } ss;
+ struct {
+ uint8_t sapi; /* SAPI to be used for this trans */
- enum gsm411_rp_state rp_state;
+ struct gsm411_smc_inst smc_inst;
+ struct gsm411_smr_inst smr_inst;
struct gsm_sms *sms;
} sms;
-#endif
};
};
diff --git a/Src/osmolib/src/host/layer23/src/common/Makefile.am b/Src/osmolib/src/host/layer23/src/common/Makefile.am
index aca2eb4..73a0fc9 100644
--- a/Src/osmolib/src/host/layer23/src/common/Makefile.am
+++ b/Src/osmolib/src/host/layer23/src/common/Makefile.am
@@ -2,5 +2,5 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)
noinst_LIBRARIES = liblayer23.a
-liblayer23_a_SOURCES = l1ctl.c l1l2_interface.c sap_interface.c lapdm.c \
+liblayer23_a_SOURCES = l1ctl.c l1l2_interface.c sap_interface.c \
logging.c networks.c sim.c sysinfo.c gps.c l1ctl_lapdm_glue.c
diff --git a/Src/osmolib/src/host/layer23/src/common/gps.c b/Src/osmolib/src/host/layer23/src/common/gps.c
index 38aae2c..e9aaa97 100644
--- a/Src/osmolib/src/host/layer23/src/common/gps.c
+++ b/Src/osmolib/src/host/layer23/src/common/gps.c
@@ -56,7 +56,12 @@ static struct osmo_fd gps_bfd;
#ifdef _HAVE_GPSD
-static struct gps_data_t* gdata;
+static struct gps_data_t* gdata = NULL;
+
+#if GPSD_API_MAJOR_VERSION >= 5
+static struct gps_data_t _gdata;
+#define gps_poll gps_read
+#endif
int osmo_gpsd_cb(struct osmo_fd *bfd, unsigned int what)
{
@@ -69,9 +74,15 @@ int osmo_gpsd_cb(struct osmo_fd *bfd, unsigned int what)
if (gdata->online)
goto gps_not_ready;
+#if GPSD_API_MAJOR_VERSION >= 5
+ /* gps has no data */
+ if (gps_waiting(gdata, 500))
+ goto gps_not_ready;
+#else
/* gps has no data */
if (gps_waiting(gdata))
goto gps_not_ready;
+#endif
/* polling returned an error */
if (gps_poll(gdata))
@@ -111,7 +122,14 @@ int osmo_gpsd_open(void)
gps_bfd.when = BSC_FD_READ;
gps_bfd.cb = osmo_gpsd_cb;
+#if GPSD_API_MAJOR_VERSION >= 5
+ if (gps_open(g.gpsd_host, g.gpsd_port, &_gdata) == -1)
+ gdata = NULL;
+ else
+ gdata = &_gdata;
+#else
gdata = gps_open(g.gpsd_host, g.gpsd_port);
+#endif
if (gdata == NULL) {
LOGP(DGPS, LOGL_ERROR, "Can't connect to gpsd\n");
return -1;
@@ -139,6 +157,9 @@ void osmo_gpsd_close(void)
osmo_fd_unregister(&gps_bfd);
+#if GPSD_API_MAJOR_VERSION >= 5
+ gps_stream(gdata, WATCH_DISABLE, NULL);
+#endif
gps_close(gdata);
gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */
}
diff --git a/Src/osmolib/src/host/layer23/src/common/l1ctl.c b/Src/osmolib/src/host/layer23/src/common/l1ctl.c
index e3ab4c9..f998ebc 100644
--- a/Src/osmolib/src/host/layer23/src/common/l1ctl.c
+++ b/Src/osmolib/src/host/layer23/src/common/l1ctl.c
@@ -44,7 +44,7 @@
#include <osmocom/bb/common/l1ctl.h>
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/l1l2_interface.h>
-#include <osmocom/bb/common/lapdm.h>
+#include <osmocom/gsm/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/codec/codec.h>
diff --git a/Src/osmolib/src/host/layer23/src/common/l1ctl_lapdm_glue.c b/Src/osmolib/src/host/layer23/src/common/l1ctl_lapdm_glue.c
index db071a3..0b2a8ed 100644
--- a/Src/osmolib/src/host/layer23/src/common/l1ctl_lapdm_glue.c
+++ b/Src/osmolib/src/host/layer23/src/common/l1ctl_lapdm_glue.c
@@ -27,7 +27,7 @@
#include <osmocom/gsm/prim.h>
#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
+#include <osmocom/gsm/lapdm.h>
/* LAPDm wants to send a PH-* primitive to the physical layer (L1) */
int l1ctl_ph_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
diff --git a/Src/osmolib/src/host/layer23/src/common/l1l2_interface.c b/Src/osmolib/src/host/layer23/src/common/l1l2_interface.c
index abaa64f..d89995d 100644
--- a/Src/osmolib/src/host/layer23/src/common/l1l2_interface.c
+++ b/Src/osmolib/src/host/layer23/src/common/l1l2_interface.c
@@ -45,7 +45,7 @@
static int layer2_read(struct osmo_fd *fd)
{
struct msgb *msg;
- u_int16_t len;
+ uint16_t len;
int rc;
msg = msgb_alloc_headroom(GSM_L2_LENGTH+GSM_L2_HEADROOM, GSM_L2_HEADROOM, "Layer2");
@@ -150,6 +150,7 @@ int layer2_close(struct osmocom_ms *ms)
close(ms->l2_wq.bfd.fd);
ms->l2_wq.bfd.fd = -1;
osmo_fd_unregister(&ms->l2_wq.bfd);
+ osmo_wqueue_clear(&ms->l2_wq);
return 0;
}
diff --git a/Src/osmolib/src/host/layer23/src/common/logging.c b/Src/osmolib/src/host/layer23/src/common/logging.c
index 82ce914..d8fd076 100644
--- a/Src/osmolib/src/host/layer23/src/common/logging.c
+++ b/Src/osmolib/src/host/layer23/src/common/logging.c
@@ -68,6 +68,12 @@ static const struct log_info_cat default_categories[] = {
.color = "\033[1;33m",
.enabled = 1, .loglevel = LOGL_DEBUG,
},
+ [DSS] = {
+ .name = "DSS",
+ .description = "Supplenmentary Services",
+ .color = "\033[1;35m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
[DSMS] = {
.name = "DSMS",
.description = "Short Message Service",
@@ -91,11 +97,6 @@ static const struct log_info_cat default_categories[] = {
.color = "\033[33m",
.enabled = 1, .loglevel = LOGL_DEBUG,
},
- [DLAPDM] = {
- .name = "DLAPDM",
- .description = "LAPDm Layer2",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
[DL1C] = {
.name = "DL1C",
.description = "Layer 1 Control",
diff --git a/Src/osmolib/src/host/layer23/src/common/main.c b/Src/osmolib/src/host/layer23/src/common/main.c
index 751f95e..eb47b26 100644
--- a/Src/osmolib/src/host/layer23/src/common/main.c
+++ b/Src/osmolib/src/host/layer23/src/common/main.c
@@ -26,7 +26,6 @@
#include <osmocom/bb/common/l1l2_interface.h>
#include <osmocom/bb/common/sap_interface.h>
#include <osmocom/bb/misc/layer3.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/l23_app.h>
diff --git a/Src/osmolib/src/host/layer23/src/common/networks.c b/Src/osmolib/src/host/layer23/src/common/networks.c
index 63221f0..40b70a1 100644
--- a/Src/osmolib/src/host/layer23/src/common/networks.c
+++ b/Src/osmolib/src/host/layer23/src/common/networks.c
@@ -1787,7 +1787,7 @@ int gsm_match_mcc(uint16_t mcc, char *imsi)
}
/* GSM 03.22 Annex A */
-int gsm_match_mnc(uint16_t mcc, uint8_t mnc, char *imsi)
+int gsm_match_mnc(uint16_t mcc, uint16_t mnc, char *imsi)
{
uint16_t sim_mnc;
diff --git a/Src/osmolib/src/host/layer23/src/common/sap_interface.c b/Src/osmolib/src/host/layer23/src/common/sap_interface.c
index fd5cdc3..1dad748 100644
--- a/Src/osmolib/src/host/layer23/src/common/sap_interface.c
+++ b/Src/osmolib/src/host/layer23/src/common/sap_interface.c
@@ -45,7 +45,7 @@
static int sap_read(struct osmo_fd *fd)
{
struct msgb *msg;
- u_int16_t len;
+ uint16_t len;
int rc;
struct osmocom_ms *ms = (struct osmocom_ms *) fd->data;
@@ -150,6 +150,7 @@ int sap_close(struct osmocom_ms *ms)
close(ms->sap_wq.bfd.fd);
ms->sap_wq.bfd.fd = -1;
osmo_fd_unregister(&ms->sap_wq.bfd);
+ osmo_wqueue_clear(&ms->sap_wq);
return 0;
}
diff --git a/Src/osmolib/src/host/layer23/src/common/sim.c b/Src/osmolib/src/host/layer23/src/common/sim.c
index 3aca693..8c89cf0 100644
--- a/Src/osmolib/src/host/layer23/src/common/sim.c
+++ b/Src/osmolib/src/host/layer23/src/common/sim.c
@@ -1045,8 +1045,25 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg)
ntohs(ef->file_id), sim->file);
goto sim_error;
}
- /* get length of file */
- ef_len = ntohs(ef->file_size);
+ /* check for record */
+ if (length >= 15 && ef->length >= 2 && ef->structure != 0x00) {
+ /* get length of record */
+ ef_len = ntohs(ef->file_size);
+ if (ef_len < data[14]) {
+ LOGP(DSIM, LOGL_NOTICE, "total length is "
+ "smaller (%d) than record size (%d)\n",
+ ef_len, data[14]);
+ goto request_error;
+ }
+ ef_len = data[14];
+ LOGP(DSIM, LOGL_NOTICE, "selected record (len %d "
+ "structure %d)\n", ef_len, ef->structure);
+ } else {
+ /* get length of file */
+ ef_len = ntohs(ef->file_size);
+ LOGP(DSIM, LOGL_NOTICE, "selected file (len %d)\n",
+ ef_len);
+ }
/* do file command */
sim->job_state = SIM_JST_WAIT_FILE;
switch (sh->job_type) {
diff --git a/Src/osmolib/src/host/layer23/src/misc/app_bcch_scan.c b/Src/osmolib/src/host/layer23/src/misc/app_bcch_scan.c
index 4c31f1a..7b21ed7 100644
--- a/Src/osmolib/src/host/layer23/src/misc/app_bcch_scan.c
+++ b/Src/osmolib/src/host/layer23/src/misc/app_bcch_scan.c
@@ -23,7 +23,6 @@
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/l23_app.h>
#include <osmocom/bb/misc/layer3.h>
diff --git a/Src/osmolib/src/host/layer23/src/misc/app_cbch_sniff.c b/Src/osmolib/src/host/layer23/src/misc/app_cbch_sniff.c
index fb043db..2f45e48 100644
--- a/Src/osmolib/src/host/layer23/src/misc/app_cbch_sniff.c
+++ b/Src/osmolib/src/host/layer23/src/misc/app_cbch_sniff.c
@@ -24,7 +24,6 @@
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/l23_app.h>
#include <osmocom/bb/misc/layer3.h>
diff --git a/Src/osmolib/src/host/layer23/src/misc/app_ccch_scan.c b/Src/osmolib/src/host/layer23/src/misc/app_ccch_scan.c
index 2f60505..d301b7b 100644
--- a/Src/osmolib/src/host/layer23/src/misc/app_ccch_scan.c
+++ b/Src/osmolib/src/host/layer23/src/misc/app_ccch_scan.c
@@ -33,7 +33,6 @@
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/misc/rslms.h>
#include <osmocom/bb/misc/layer3.h>
#include <osmocom/bb/common/osmocom_data.h>
@@ -162,7 +161,8 @@ static void dump_bcch(struct osmocom_ms *ms, uint8_t tc, const uint8_t *data)
case GSM48_MT_RR_SYSINFO_5ter:
break;
default:
- fprintf(stderr, "\tUnknown SI");
+ LOGP(DRR, LOGL_ERROR, "Unknown SI: %d\n",
+ si_hdr->system_information);
break;
};
}
@@ -352,7 +352,7 @@ static int gsm48_rx_paging_p2(struct msgb *msg, struct osmocom_ms *ms)
chan_need(pag->cneed1), pag->tmsi1);
LOGP(DRR, LOGL_NOTICE, "Paging2: %s chan %s to TMSI M(0x%x) \n",
pag_print_mode(pag->pag_mode),
- chan_need(pag->cneed1), pag->tmsi2);
+ chan_need(pag->cneed2), pag->tmsi2);
/* no optional element */
if (msgb_l3len(msg) < sizeof(*pag) + 3)
@@ -380,6 +380,32 @@ static int gsm48_rx_paging_p2(struct msgb *msg, struct osmocom_ms *ms)
return 0;
}
+static int gsm48_rx_paging_p3(struct msgb *msg, struct osmocom_ms *ms)
+{
+ struct gsm48_paging3 *pag;
+
+ if (msgb_l3len(msg) < sizeof(*pag)) {
+ LOGP(DRR, LOGL_ERROR, "Paging3 message is too small.\n");
+ return -1;
+ }
+
+ pag = msgb_l3(msg);
+ LOGP(DRR, LOGL_NOTICE, "Paging1: %s chan %s to TMSI M(0x%x) \n",
+ pag_print_mode(pag->pag_mode),
+ chan_need(pag->cneed1), pag->tmsi1);
+ LOGP(DRR, LOGL_NOTICE, "Paging2: %s chan %s to TMSI M(0x%x) \n",
+ pag_print_mode(pag->pag_mode),
+ chan_need(pag->cneed2), pag->tmsi2);
+ LOGP(DRR, LOGL_NOTICE, "Paging3: %s chan %s to TMSI M(0x%x) \n",
+ pag_print_mode(pag->pag_mode),
+ "n/a ", pag->tmsi3);
+ LOGP(DRR, LOGL_NOTICE, "Paging4: %s chan %s to TMSI M(0x%x) \n",
+ pag_print_mode(pag->pag_mode),
+ "n/a ", pag->tmsi4);
+
+ return 0;
+}
+
int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
{
struct gsm48_system_information_type_header *sih = msgb_l3(msg);
@@ -396,7 +422,7 @@ int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
gsm48_rx_paging_p2(msg, ms);
break;
case GSM48_MT_RR_PAG_REQ_3:
- LOGP(DRR, LOGL_ERROR, "PAGING of type 3 is not implemented.\n");
+ gsm48_rx_paging_p3(msg, ms);
break;
case GSM48_MT_RR_IMM_ASS:
gsm48_rx_imm_ass(msg, ms);
diff --git a/Src/osmolib/src/host/layer23/src/misc/app_echo_test.c b/Src/osmolib/src/host/layer23/src/misc/app_echo_test.c
index 3d937d2..3a0ee0f 100644
--- a/Src/osmolib/src/host/layer23/src/misc/app_echo_test.c
+++ b/Src/osmolib/src/host/layer23/src/misc/app_echo_test.c
@@ -23,7 +23,6 @@
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/l23_app.h>
#include <osmocom/bb/misc/layer3.h>
diff --git a/Src/osmolib/src/host/layer23/src/misc/bcch_scan.c b/Src/osmolib/src/host/layer23/src/misc/bcch_scan.c
index ddd0eea..4636c9a 100644
--- a/Src/osmolib/src/host/layer23/src/misc/bcch_scan.c
+++ b/Src/osmolib/src/host/layer23/src/misc/bcch_scan.c
@@ -40,7 +40,6 @@
#include <osmocom/bb/common/l1ctl.h>
#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
/* somewhere in 05.08 */
@@ -275,7 +274,7 @@ static int bscan_sig_cb(unsigned int subsys, unsigned int signal,
rc = get_next_arfcn(&fps);
if (rc < 0) {
fps.state = BSCAN_S_DONE;
- return;
+ return 0;
}
_cinfo_start_arfcn(rc);
break;
diff --git a/Src/osmolib/src/host/layer23/src/misc/catcher b/Src/osmolib/src/host/layer23/src/misc/catcher
index 647207e..ef3d795 100644..100755
--- a/Src/osmolib/src/host/layer23/src/misc/catcher
+++ b/Src/osmolib/src/host/layer23/src/misc/catcher
Binary files differ
diff --git a/Src/osmolib/src/host/layer23/src/misc/catcher.c b/Src/osmolib/src/host/layer23/src/misc/catcher.c
index b97be3d..03bf442 100644
--- a/Src/osmolib/src/host/layer23/src/misc/catcher.c
+++ b/Src/osmolib/src/host/layer23/src/misc/catcher.c
@@ -39,7 +39,6 @@
#include <osmocom/bb/common/l1ctl.h>
#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/networks.h>
#include <osmocom/bb/common/gps.h>
@@ -190,14 +189,16 @@ static void log_sysinfo(void)
// arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc),
// gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str);
LOGFILE("[SysInfo]\n");
- LOGFILE("country %s\n", gsm_get_mcc(s->mcc))
- LOGFILE("provider %s\n", gsm_get_mnc(s->mcc, s->mnc))
- LOGFILE("arfcn %d\n", s->arfcn);
+ LOGFILE("Country: %s\n", gsm_get_mcc(s->mcc));
+ LOGFILE("Provider: %s\n", gsm_get_mnc(s->mcc, s->mnc));
+ LOGFILE("ARFCN: %d\n", s->arfcn);
+ LOGFILE("Cell_ID: %d\n", s->cell_id);
+ LOGFILE("LAC: %d\n", s->lac);
//log_time();
//log_gps();
- //LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7);
+ LOGFILE("BSIC: %d,%d\n", s->bsic >> 3, s->bsic & 7);
rxlev = meas->rxlev / meas->frames - 110;
- LOGFILE("rxlev %d\n", rxlev);
+ LOGFILE("rxlev: %d\n", rxlev);
//if (s->si1)
// log_frame("si1", s->si1_msg);
if (s->si2)
diff --git a/Src/osmolib/src/host/layer23/src/misc/cell_log.c b/Src/osmolib/src/host/layer23/src/misc/cell_log.c
index 1a9c33c..aa964f4 100644
--- a/Src/osmolib/src/host/layer23/src/misc/cell_log.c
+++ b/Src/osmolib/src/host/layer23/src/misc/cell_log.c
@@ -39,7 +39,6 @@
#include <osmocom/bb/common/l1ctl.h>
#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/networks.h>
#include <osmocom/bb/common/gps.h>
diff --git a/Src/osmolib/src/host/layer23/src/misc/rslms.c b/Src/osmolib/src/host/layer23/src/misc/rslms.c
index 68956f9..455e663 100644
--- a/Src/osmolib/src/host/layer23/src/misc/rslms.c
+++ b/Src/osmolib/src/host/layer23/src/misc/rslms.c
@@ -30,7 +30,7 @@
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/lapdm.h>
+#include <osmocom/gsm/lapdm.h>
#include <osmocom/bb/misc/rslms.h>
#include <osmocom/bb/misc/layer3.h>
#include <osmocom/bb/common/osmocom_data.h>
diff --git a/Src/osmolib/src/host/layer23/src/mobile/Makefile.am b/Src/osmolib/src/host/layer23/src/mobile/Makefile.am
index 4cff9ef..f3365af 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/Makefile.am
+++ b/Src/osmolib/src/host/layer23/src/mobile/Makefile.am
@@ -3,8 +3,8 @@ AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)
LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS)
noinst_LIBRARIES = libmobile.a
-libmobile_a_SOURCES = gsm322.c gsm48_cc.c gsm48_mm.c gsm48_rr.c \
- mnccms.c settings.c subscriber.c support.c \
+libmobile_a_SOURCES = gsm322.c gsm480_ss.c gsm411_sms.c gsm48_cc.c gsm48_mm.c \
+ gsm48_rr.c mnccms.c settings.c subscriber.c support.c \
transaction.c vty_interface.c voice.c mncc_sock.c
bin_PROGRAMS = mobile
diff --git a/Src/osmolib/src/host/layer23/src/mobile/app_mobile.c b/Src/osmolib/src/host/layer23/src/mobile/app_mobile.c
index ada9480..da388b2 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/app_mobile.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/app_mobile.c
@@ -28,10 +28,11 @@
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/l1l2_interface.h>
#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/gps.h>
#include <osmocom/bb/mobile/gsm48_rr.h>
+#include <osmocom/bb/mobile/gsm480_ss.h>
+#include <osmocom/bb/mobile/gsm411_sms.h>
#include <osmocom/bb/mobile/vty.h>
#include <osmocom/bb/mobile/app_mobile.h>
#include <osmocom/bb/mobile/mncc.h>
@@ -145,6 +146,8 @@ int mobile_exit(struct osmocom_ms *ms, int force)
gsm48_rr_exit(ms);
gsm_subscr_exit(ms);
gsm48_cc_exit(ms);
+ gsm480_ss_exit(ms);
+ gsm411_sms_exit(ms);
gsm_sim_exit(ms);
lapdm_channel_exit(&ms->lapdm_channel);
@@ -168,6 +171,8 @@ int mobile_init(struct osmocom_ms *ms)
gsm_sim_init(ms);
gsm48_cc_init(ms);
+ gsm480_ss_init(ms);
+ gsm411_sms_init(ms);
gsm_voice_init(ms);
gsm_subscr_init(ms);
gsm48_rr_init(ms);
@@ -334,6 +339,8 @@ int l23_app_exit(void)
osmo_gps_close();
+ telnet_exit();
+
return 0;
}
diff --git a/Src/osmolib/src/host/layer23/src/mobile/gsm322.c b/Src/osmolib/src/host/layer23/src/mobile/gsm322.c
index 9384743..ce5e1e1 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/gsm322.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/gsm322.c
@@ -1840,10 +1840,11 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc,
/* loop through all scanned frequencies and select cell.
* if an index is given (arfci), we just check this cell only */
- if (index >= 0)
+ if (index >= 0) {
start = end = index;
- else
+ } else {
start = 0; end = 1023+299;
+ }
for (i = start; i <= end; i++) {
cs->list[i].flags &= ~GSM322_CS_FLAG_TEMP_AA;
s = cs->list[i].sysinfo;
@@ -3024,9 +3025,10 @@ int gsm322_l1_signal(unsigned int subsys, unsigned int signal,
cs = &ms->cellsel;
LOGP(DCS, LOGL_INFO, "Loss of CCCH.\n");
if (cs->selected && cs->sel_arfcn == cs->arfcn) {
- LOGP(DCS, LOGL_INFO, "Unselect cell due to loss\n");
- /* unset selected cell */
- gsm322_unselect_cell(cs);
+ /* do not unselect cell */
+ LOGP(DCS, LOGL_INFO, "Keep cell selected after loss, "
+ "so we can use the Neighbour cell information "
+ "for cell re-selection.\n");
}
stop_cs_timer(cs);
gsm322_cs_loss(cs);
diff --git a/Src/osmolib/src/host/layer23/src/mobile/gsm411_sms.c b/Src/osmolib/src/host/layer23/src/mobile/gsm411_sms.c
new file mode 100644
index 0000000..4347e86
--- /dev/null
+++ b/Src/osmolib/src/host/layer23/src/mobile/gsm411_sms.c
@@ -0,0 +1,941 @@
+/*
+ * Code based on work of:
+ * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ *
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/bb/common/logging.h>
+#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/bb/mobile/mncc.h>
+#include <osmocom/bb/mobile/transaction.h>
+#include <osmocom/bb/mobile/gsm411_sms.h>
+#include <osmocom/gsm/gsm0411_utils.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/bb/mobile/vty.h>
+
+#define UM_SAPI_SMS 3
+
+extern void *l23_ctx;
+static uint32_t new_callref = 0x40000001;
+
+static int gsm411_rl_recv(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg);
+static int gsm411_mn_recv(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg);
+static int gsm411_mm_send(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type);
+static int gsm411_mn_send(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg);
+/*
+ * init / exit
+ */
+
+int gsm411_sms_init(struct osmocom_ms *ms)
+{
+ LOGP(DLSMS, LOGL_INFO, "init SMS\n");
+
+ return 0;
+}
+
+int gsm411_sms_exit(struct osmocom_ms *ms)
+{
+ struct gsm_trans *trans, *trans2;
+
+ LOGP(DLSMS, LOGL_INFO, "exit SMS processes for %s\n", ms->name);
+
+ llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
+ if (trans->protocol == GSM48_PDISC_SMS) {
+ LOGP(DLSMS, LOGL_NOTICE, "Free pendig "
+ "SMS-transaction.\n");
+ trans_free(trans);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * SMS content
+ */
+
+struct gsm_sms *sms_alloc(void)
+{
+ return talloc_zero(l23_ctx, struct gsm_sms);
+}
+
+void sms_free(struct gsm_sms *sms)
+{
+ talloc_free(sms);
+}
+
+struct gsm_sms *sms_from_text(const char *receiver, int dcs, const char *text)
+{
+ struct gsm_sms *sms = sms_alloc();
+
+ if (!sms)
+ return NULL;
+
+ strncpy(sms->text, text, sizeof(sms->text)-1);
+
+ /* FIXME: don't use ID 1 static */
+ sms->reply_path_req = 0;
+ sms->status_rep_req = 0;
+ sms->ud_hdr_ind = 0;
+ sms->protocol_id = 0; /* implicit */
+ sms->data_coding_scheme = dcs;
+ strncpy(sms->address, receiver, sizeof(sms->address)-1);
+ /* Generate user_data */
+ sms->user_data_len = gsm_7bit_encode(sms->user_data, sms->text);
+
+ return sms;
+}
+
+static int gsm411_sms_report(struct osmocom_ms *ms, struct gsm_sms *sms,
+ uint8_t cause)
+{
+ vty_notify(ms, NULL);
+ if (!cause)
+ vty_notify(ms, "SMS to %s successfull\n", sms->address);
+ else
+ vty_notify(ms, "SMS to %s failed: %s\n", sms->address,
+ get_value_string(gsm411_rp_cause_strs, cause));
+
+ return 0;
+}
+/*
+ * transaction
+ */
+
+/* SMS Specific transaction release.
+ * gets called by trans_free, DO NOT CALL YOURSELF!
+ */
+void _gsm411_sms_trans_free(struct gsm_trans *trans)
+{
+ gsm411_smr_clear(&trans->sms.smr_inst);
+ gsm411_smc_clear(&trans->sms.smc_inst);
+
+ if (trans->sms.sms) {
+ LOGP(DLSMS, LOGL_ERROR, "Transaction contains SMS.\n");
+ gsm411_sms_report(trans->ms, trans->sms.sms,
+ GSM411_RP_CAUSE_MO_SMS_REJECTED);
+ sms_free(trans->sms.sms);
+ trans->sms.sms = NULL;
+ }
+}
+
+/* release MM connection, free transaction */
+static int gsm411_trans_free(struct gsm_trans *trans)
+{
+ struct msgb *nmsg;
+
+ /* release MM connection */
+ nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_REQ, trans->callref,
+ trans->transaction_id, trans->sms.sapi);
+ if (!nmsg)
+ return -ENOMEM;
+ LOGP(DLSMS, LOGL_INFO, "Sending MMSMS_REL_REQ\n");
+ gsm48_mmxx_downmsg(trans->ms, nmsg);
+
+ trans->callref = 0;
+ trans_free(trans);
+
+ return 0;
+}
+
+/*
+ * receive SMS
+ */
+
+/* now here comes our SMS */
+static int gsm340_rx_sms_deliver(struct osmocom_ms *ms, struct msgb *msg,
+ struct gsm_sms *gsms)
+{
+ const char osmocomsms[] = ".osmocom/bb/sms.txt";
+ int len;
+ const char *home;
+ char *sms_file;
+ char vty_text[sizeof(gsms->text)], *p;
+ FILE *fp;
+
+ /* remove linefeeds and show at VTY */
+ strcpy(vty_text, gsms->text);
+ for (p = vty_text; *p; p++) {
+ if (*p == '\n' || *p == '\r')
+ *p = ' ';
+ }
+ vty_notify(ms, NULL);
+ vty_notify(ms, "SMS from %s: '%s'\n", gsms->address, vty_text);
+
+ home = getenv("HOME");
+ if (!home) {
+fail:
+ fprintf(stderr, "Can't deliver SMS, be sure to create '%s' in "
+ "your home directory.\n", osmocomsms);
+ return GSM411_RP_CAUSE_MT_MEM_EXCEEDED;
+ }
+ len = strlen(home) + 1 + sizeof(osmocomsms);
+ sms_file = talloc_size(l23_ctx, len);
+ if (!sms_file)
+ goto fail;
+ snprintf(sms_file, len, "%s/%s", home, osmocomsms);
+
+ fp = fopen(sms_file, "a");
+ if (!fp)
+ goto fail;
+ fprintf(fp, "[SMS from %s]\n%s\n", gsms->address, gsms->text);
+ fclose(fp);
+
+ talloc_free(sms_file);
+
+ return 0;
+}
+
+/* process an incoming TPDU (called from RP-DATA)
+ * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */
+static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg)
+{
+ uint8_t *smsp = msgb_sms(msg);
+ struct gsm_sms *gsms;
+ unsigned int sms_alphabet;
+ uint8_t sms_mti, sms_mms;
+ uint8_t oa_len_bytes;
+ uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
+ int rc = 0;
+
+ gsms = sms_alloc();
+
+ /* invert those fields where 0 means active/present */
+ sms_mti = *smsp & 0x03;
+ sms_mms = !!(*smsp & 0x04);
+ gsms->status_rep_req = (*smsp & 0x20);
+ gsms->ud_hdr_ind = (*smsp & 0x40);
+ gsms->reply_path_req = (*smsp & 0x80);
+ smsp++;
+
+ /* length in bytes of the originate address */
+ oa_len_bytes = 2 + *smsp/2 + *smsp%2;
+ if (oa_len_bytes > 12) {
+ LOGP(DLSMS, LOGL_ERROR, "Originate Address > 12 bytes ?!?\n");
+ rc = GSM411_RP_CAUSE_SEMANT_INC_MSG;
+ goto out;
+ }
+ memset(address_lv, 0, sizeof(address_lv));
+ memcpy(address_lv, smsp, oa_len_bytes);
+ /* mangle first byte to reflect length in bytes, not digits */
+ address_lv[0] = oa_len_bytes - 1;
+ /* convert to real number */
+ if (((smsp[1] & 0x70) >> 4) == 1)
+ strcpy(gsms->address, "+");
+ else if (((smsp[1] & 0x70) >> 4) == 2)
+ strcpy(gsms->address, "0");
+ else
+ gsms->address[0] = '\0';
+ gsm48_decode_bcd_number(gsms->address + strlen(gsms->address),
+ sizeof(gsms->address) - strlen(gsms->address), address_lv, 1);
+ smsp += oa_len_bytes;
+
+ gsms->protocol_id = *smsp++;
+ gsms->data_coding_scheme = *smsp++;
+
+ sms_alphabet = gsm338_get_sms_alphabet(gsms->data_coding_scheme);
+ if (sms_alphabet == 0xffffffff) {
+ sms_free(gsms);
+ return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
+ }
+
+ /* get timestamp */
+ gsms->time = gsm340_scts(smsp);
+ smsp += 7;
+
+ /* user data */
+ gsms->user_data_len = *smsp++;
+ if (gsms->user_data_len) {
+ memcpy(gsms->user_data, smsp, gsms->user_data_len);
+
+ switch (sms_alphabet) {
+ case DCS_7BIT_DEFAULT:
+ gsm_7bit_decode(gsms->text, smsp, gsms->user_data_len);
+ break;
+ case DCS_8BIT_DATA:
+ case DCS_UCS2:
+ case DCS_NONE:
+ break;
+ }
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "RX SMS: MTI: 0x%02x, "
+ "MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, OA: %s, "
+ "UserDataLength: 0x%02x, UserData: \"%s\"\n",
+ sms_mti, gsms->msg_ref,
+ gsms->protocol_id, gsms->data_coding_scheme, gsms->address,
+ gsms->user_data_len,
+ sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text :
+ osmo_hexdump(gsms->user_data,
+ gsms->user_data_len));
+
+ switch (sms_mti) {
+ case GSM340_SMS_DELIVER_SC2MS:
+ /* MS is receiving an SMS */
+ rc = gsm340_rx_sms_deliver(trans->ms, msg, gsms);
+ break;
+ case GSM340_SMS_STATUS_REP_SC2MS:
+ case GSM340_SMS_SUBMIT_REP_SC2MS:
+ LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti);
+ rc = GSM411_RP_CAUSE_IE_NOTEXIST;
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti);
+ rc = GSM411_RP_CAUSE_IE_NOTEXIST;
+ break;
+ }
+
+out:
+ sms_free(gsms);
+
+ return rc;
+}
+
+static int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref)
+{
+ struct msgb *msg = gsm411_msgb_alloc();
+
+ LOGP(DLSMS, LOGL_INFO, "TX: SMS RP ACK\n");
+
+ gsm411_push_rp_header(msg, GSM411_MT_RP_ACK_MO, msg_ref);
+ return gsm411_smr_send(&trans->sms.smr_inst, GSM411_SM_RL_REPORT_REQ,
+ msg);
+}
+
+static int gsm411_send_rp_error(struct gsm_trans *trans,
+ uint8_t msg_ref, uint8_t cause)
+{
+ struct msgb *msg = gsm411_msgb_alloc();
+
+ msgb_tv_put(msg, 1, cause);
+
+ LOGP(DLSMS, LOGL_NOTICE, "TX: SMS RP ERROR, cause %d (%s)\n", cause,
+ get_value_string(gsm411_rp_cause_strs, cause));
+
+ gsm411_push_rp_header(msg, GSM411_MT_RP_ERROR_MO, msg_ref);
+ return gsm411_smr_send(&trans->sms.smr_inst, GSM411_SM_RL_REPORT_REQ,
+ msg);
+}
+
+/* Receive a 04.11 TPDU inside RP-DATA / user data */
+static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
+ struct gsm411_rp_hdr *rph,
+ uint8_t src_len, uint8_t *src,
+ uint8_t dst_len, uint8_t *dst,
+ uint8_t tpdu_len, uint8_t *tpdu)
+{
+ int rc = 0;
+
+ if (dst_len && dst)
+ LOGP(DLSMS, LOGL_ERROR, "RP-DATA (MT) with DST ?!?\n");
+
+ if (!src_len || !src || !tpdu_len || !tpdu) {
+ LOGP(DLSMS, LOGL_ERROR,
+ "RP-DATA (MO) without DST or TPDU ?!?\n");
+ gsm411_send_rp_error(trans, rph->msg_ref,
+ GSM411_RP_CAUSE_INV_MAND_INF);
+ return -EIO;
+ }
+ msg->l4h = tpdu;
+
+ LOGP(DLSMS, LOGL_INFO, "DST(%u,%s)\n", src_len,
+ osmo_hexdump(src, src_len));
+ LOGP(DLSMS, LOGL_INFO, "TPDU(%u,%s)\n", msg->tail-msg->l4h,
+ osmo_hexdump(msg->l4h, msg->tail-msg->l4h));
+
+ rc = gsm340_rx_tpdu(trans, msg);
+ if (rc == 0)
+ return gsm411_send_rp_ack(trans, rph->msg_ref);
+ else if (rc > 0)
+ return gsm411_send_rp_error(trans, rph->msg_ref, rc);
+ else
+ return rc;
+}
+
+/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
+static int gsm411_rx_rp_data(struct msgb *msg, struct gsm_trans *trans,
+ struct gsm411_rp_hdr *rph)
+{
+ uint8_t src_len, dst_len, rpud_len;
+ uint8_t *src = NULL, *dst = NULL , *rp_ud = NULL;
+
+ /* in the MO case, this should always be zero length */
+ src_len = rph->data[0];
+ if (src_len)
+ src = &rph->data[1];
+
+ dst_len = rph->data[1+src_len];
+ if (dst_len)
+ dst = &rph->data[1+src_len+1];
+
+ rpud_len = rph->data[1+src_len+1+dst_len];
+ if (rpud_len)
+ rp_ud = &rph->data[1+src_len+1+dst_len+1];
+
+ LOGP(DLSMS, LOGL_INFO, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n",
+ src_len, dst_len, rpud_len);
+ return gsm411_rx_rp_ud(msg, trans, rph, src_len, src, dst_len, dst,
+ rpud_len, rp_ud);
+}
+
+/* receive RL DATA */
+static int gsm411_rx_rl_data(struct msgb *msg, struct gsm48_hdr *gh,
+ struct gsm_trans *trans)
+{
+ struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
+ uint8_t msg_type = rp_data->msg_type & 0x07;
+ int rc = 0;
+
+ switch (msg_type) {
+ case GSM411_MT_RP_DATA_MT:
+ LOGP(DLSMS, LOGL_INFO, "RX SMS RP-DATA (MT)\n");
+ rc = gsm411_rx_rp_data(msg, trans, rp_data);
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+ gsm411_trans_free(trans);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+/*
+ * send SMS
+ */
+
+/* Receive a 04.11 RP-ACK message (response to RP-DATA from us) */
+static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans,
+ struct gsm411_rp_hdr *rph)
+{
+ struct osmocom_ms *ms = trans->ms;
+ struct gsm_sms *sms = trans->sms.sms;
+
+ /* Acnkowledgement to MT RP_DATA, i.e. the MS confirms it
+ * successfully received a SMS. We can now safely mark it as
+ * transmitted */
+
+ if (!sms) {
+ LOGP(DLSMS, LOGL_ERROR, "RX RP-ACK but no sms in "
+ "transaction?!?\n");
+ return gsm411_send_rp_error(trans, rph->msg_ref,
+ GSM411_RP_CAUSE_PROTOCOL_ERR);
+ }
+
+ gsm411_sms_report(ms, sms, 0);
+
+ sms_free(sms);
+ trans->sms.sms = NULL;
+
+ return 0;
+}
+
+static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans,
+ struct gsm411_rp_hdr *rph)
+{
+ struct osmocom_ms *ms = trans->ms;
+ struct gsm_sms *sms = trans->sms.sms;
+ uint8_t cause_len = rph->data[0];
+ uint8_t cause = rph->data[1];
+
+ /* Error in response to MT RP_DATA, i.e. the MS did not
+ * successfully receive the SMS. We need to investigate
+ * the cause and take action depending on it */
+
+ LOGP(DLSMS, LOGL_NOTICE, "%s: RX SMS RP-ERROR, cause %d:%d (%s)\n",
+ trans->ms->name, cause_len, cause,
+ get_value_string(gsm411_rp_cause_strs, cause));
+
+ if (!sms) {
+ LOGP(DLSMS, LOGL_ERROR,
+ "RX RP-ERR, but no sms in transaction?!?\n");
+ return -EINVAL;
+#if 0
+ return gsm411_send_rp_error(trans, rph->msg_ref,
+ GSM411_RP_CAUSE_PROTOCOL_ERR);
+#endif
+ }
+
+ gsm411_sms_report(ms, sms, cause);
+
+ sms_free(sms);
+ trans->sms.sms = NULL;
+
+ return 0;
+}
+
+/* receive RL REPORT */
+static int gsm411_rx_rl_report(struct msgb *msg, struct gsm48_hdr *gh,
+ struct gsm_trans *trans)
+{
+ struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
+ uint8_t msg_type = rp_data->msg_type & 0x07;
+ int rc = 0;
+
+ switch (msg_type) {
+ case GSM411_MT_RP_ACK_MT:
+ LOGP(DLSMS, LOGL_INFO, "RX SMS RP-ACK (MT)\n");
+ rc = gsm411_rx_rp_ack(msg, trans, rp_data);
+ break;
+ case GSM411_MT_RP_ERROR_MT:
+ LOGP(DLSMS, LOGL_INFO, "RX SMS RP-ERROR (MT)\n");
+ rc = gsm411_rx_rp_error(msg, trans, rp_data);
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+ gsm411_trans_free(trans);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+/* generate a msgb containing a TPDU derived from struct gsm_sms,
+ * returns total size of TPDU */
+static int gsm340_gen_tpdu(struct msgb *msg, struct gsm_sms *sms)
+{
+ uint8_t *smsp;
+ uint8_t da[12]; /* max len per 03.40 */
+ uint8_t da_len = 0;
+ uint8_t octet_len;
+ unsigned int old_msg_len = msg->len;
+ uint8_t sms_vpf = GSM340_TP_VPF_NONE;
+ uint8_t sms_vp;
+
+ /* generate first octet with masked bits */
+ smsp = msgb_put(msg, 1);
+ /* TP-MTI (message type indicator) */
+ *smsp = GSM340_SMS_SUBMIT_MS2SC;
+ /* TP-RD */
+ if (0 /* FIXME */)
+ *smsp |= 0x04;
+ /* TP-VPF */
+ *smsp |= (sms_vpf << 3);
+ /* TP-SRI(deliver)/SRR(submit) */
+ if (sms->status_rep_req)
+ *smsp |= 0x20;
+ /* TP-UDHI (indicating TP-UD contains a header) */
+ if (sms->ud_hdr_ind)
+ *smsp |= 0x40;
+ /* TP-RP */
+ if (sms->reply_path_req)
+ *smsp |= 0x80;
+
+ /* generate message ref */
+ smsp = msgb_put(msg, 1);
+ *smsp = sms->msg_ref;
+
+ /* generate destination address */
+ if (sms->address[0] == '+')
+ da_len = gsm340_gen_oa(da, sizeof(da), 0x1, 0x1,
+ sms->address + 1);
+ else
+ da_len = gsm340_gen_oa(da, sizeof(da), 0x0, 0x1, sms->address);
+ smsp = msgb_put(msg, da_len);
+ memcpy(smsp, da, da_len);
+
+ /* generate TP-PID */
+ smsp = msgb_put(msg, 1);
+ *smsp = sms->protocol_id;
+
+ /* generate TP-DCS */
+ smsp = msgb_put(msg, 1);
+ *smsp = sms->data_coding_scheme;
+
+ /* generate TP-VP */
+ switch (sms_vpf) {
+ case GSM340_TP_VPF_NONE:
+ sms_vp = 0;
+ break;
+ default:
+ fprintf(stderr, "VPF unsupported, please fix!\n");
+ exit(0);
+ }
+ smsp = msgb_put(msg, sms_vp);
+
+ /* generate TP-UDL */
+ smsp = msgb_put(msg, 1);
+ *smsp = sms->user_data_len;
+
+ /* generate TP-UD */
+ switch (gsm338_get_sms_alphabet(sms->data_coding_scheme)) {
+ case DCS_7BIT_DEFAULT:
+ octet_len = sms->user_data_len*7/8;
+ if (sms->user_data_len*7%8 != 0)
+ octet_len++;
+ /* Warning, user_data_len indicates the amount of septets
+ * (characters), we need amount of octets occupied */
+ smsp = msgb_put(msg, octet_len);
+ memcpy(smsp, sms->user_data, octet_len);
+ break;
+ case DCS_UCS2:
+ case DCS_8BIT_DATA:
+ smsp = msgb_put(msg, sms->user_data_len);
+ memcpy(smsp, sms->user_data, sms->user_data_len);
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Unhandled Data Coding Scheme: "
+ "0x%02X\n", sms->data_coding_scheme);
+ break;
+ }
+
+ return msg->len - old_msg_len;
+}
+
+/* Take a SMS in gsm_sms structure and send it. */
+static int gsm411_tx_sms_submit(struct osmocom_ms *ms, const char *sms_sca,
+ struct gsm_sms *sms)
+{
+ struct msgb *msg;
+ struct gsm_trans *trans;
+ uint8_t *data, *rp_ud_len;
+ uint8_t msg_ref = 42;
+ int rc;
+ uint8_t transaction_id;
+ uint8_t sca[11]; /* max len per 03.40 */
+
+ LOGP(DLSMS, LOGL_INFO, "..._sms_submit()\n");
+
+ /* no running, no transaction */
+ if (!ms->started || ms->shutdown) {
+ LOGP(DLSMS, LOGL_ERROR, "Phone is down\n");
+ gsm411_sms_report(ms, sms, GSM411_RP_CAUSE_MO_TEMP_FAIL);
+ sms_free(sms);
+ return -EIO;
+ }
+
+ /* allocate transaction with dummy reference */
+ transaction_id = trans_assign_trans_id(ms, GSM48_PDISC_SMS, 0);
+ if (transaction_id < 0) {
+ LOGP(DLSMS, LOGL_ERROR, "No transaction ID available\n");
+ gsm411_sms_report(ms, sms, GSM411_RP_CAUSE_MO_CONGESTION);
+ sms_free(sms);
+ return -ENOMEM;
+ }
+ trans = trans_alloc(ms, GSM48_PDISC_SMS, transaction_id, new_callref++);
+ if (!trans) {
+ LOGP(DLSMS, LOGL_ERROR, "No memory for trans\n");
+ gsm411_sms_report(ms, sms, GSM411_RP_CAUSE_MO_TEMP_FAIL);
+ sms_free(sms);
+ return -ENOMEM;
+ }
+ gsm411_smc_init(&trans->sms.smc_inst, 0, gsm411_mn_recv,
+ gsm411_mm_send);
+ gsm411_smr_init(&trans->sms.smr_inst, 0, gsm411_rl_recv,
+ gsm411_mn_send);
+ trans->sms.sms = sms;
+ trans->sms.sapi = UM_SAPI_SMS;
+
+ msg = gsm411_msgb_alloc();
+
+ /* no orig Address */
+ data = (uint8_t *)msgb_put(msg, 1);
+ data[0] = 0x00; /* originator length == 0 */
+
+ /* Destination Address */
+ sca[1] = 0x80; /* no extension */
+ sca[1] |= ((sms_sca[0] == '+') ? 0x01 : 0x00) << 4; /* type */
+ sca[1] |= 0x1; /* plan*/
+
+ rc = gsm48_encode_bcd_number(sca, sizeof(sca), 1,
+ sms_sca + (sms_sca[0] == '+'));
+ if (rc < 0) {
+error:
+ gsm411_sms_report(ms, sms, GSM411_RP_CAUSE_SEMANT_INC_MSG);
+ gsm411_trans_free(trans);
+ msgb_free(msg);
+ return rc;
+ }
+ data = msgb_put(msg, rc);
+ memcpy(data, sca, rc);
+
+ /* obtain a pointer for the rp_ud_len, so we can fill it later */
+ rp_ud_len = (uint8_t *)msgb_put(msg, 1);
+
+ /* generate the 03.40 TPDU */
+ rc = gsm340_gen_tpdu(msg, sms);
+ if (rc < 0)
+ goto error;
+ *rp_ud_len = rc;
+
+ LOGP(DLSMS, LOGL_INFO, "TX: SMS DELIVER\n");
+
+ gsm411_push_rp_header(msg, GSM411_MT_RP_DATA_MO, msg_ref);
+ return gsm411_smr_send(&trans->sms.smr_inst, GSM411_SM_RL_DATA_REQ,
+ msg);
+}
+
+/* create and send SMS */
+int sms_send(struct osmocom_ms *ms, const char *sms_sca, const char *number,
+ const char *text)
+{
+ struct gsm_sms *sms = sms_from_text(number, 0, text);
+
+ if (!sms)
+ return -ENOMEM;
+
+ return gsm411_tx_sms_submit(ms, sms_sca, sms);
+}
+
+/*
+ * message flow between layers
+ */
+
+/* push MMSMS header and send to MM */
+static int gsm411_to_mm(struct msgb *msg, struct gsm_trans *trans,
+ int msg_type)
+{
+ struct gsm48_mmxx_hdr *mmh;
+
+ /* push RR header */
+ msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
+ mmh = (struct gsm48_mmxx_hdr *)msg->data;
+ mmh->msg_type = msg_type;
+ mmh->ref = trans->callref;
+ mmh->transaction_id = trans->transaction_id;
+ mmh->sapi = trans->sms.sapi;
+ mmh->emergency = 0;
+
+ /* send message to MM */
+ LOGP(DLSMS, LOGL_INFO, "Sending '%s' to MM (callref=%x, "
+ "transaction_id=%d, sapi=%d)\n", get_mmxx_name(msg_type),
+ trans->callref, trans->transaction_id, trans->sms.sapi);
+ return gsm48_mmxx_downmsg(trans->ms, msg);
+}
+
+/* mm_send: receive MMSMS sap message from SMC */
+static int gsm411_mm_send(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type)
+{
+ struct gsm_trans *trans =
+ container_of(inst, struct gsm_trans, sms.smc_inst);
+ int rc = 0;
+
+ switch (msg_type) {
+ case GSM411_MMSMS_EST_REQ:
+ gsm411_to_mm(msg, trans, msg_type);
+ break;
+ case GSM411_MMSMS_DATA_REQ:
+ gsm411_push_cp_header(msg, trans->protocol,
+ trans->transaction_id, cp_msg_type);
+ msg->l3h = msg->data;
+ LOGP(DLSMS, LOGL_INFO, "sending CP message (trans=%x)\n",
+ trans->transaction_id);
+ rc = gsm411_to_mm(msg, trans, msg_type);
+ break;
+ case GSM411_MMSMS_REL_REQ:
+ LOGP(DLSMS, LOGL_INFO, "Got MMSMS_REL_REQ, destroying "
+ "transaction.\n");
+ gsm411_to_mm(msg, trans, msg_type);
+ gsm411_trans_free(trans);
+ break;
+ default:
+ msgb_free(msg);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+/* mm_send: receive MNSMS sap message from SMR */
+static int gsm411_mn_send(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg)
+{
+ struct gsm_trans *trans =
+ container_of(inst, struct gsm_trans, sms.smr_inst);
+
+ /* forward to SMC */
+ return gsm411_smc_send(&trans->sms.smc_inst, msg_type, msg);
+}
+
+/* receive SM-RL sap message from SMR
+ * NOTE: Message is freed by sender
+ */
+static int gsm411_rl_recv(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg)
+{
+ struct gsm_trans *trans =
+ container_of(inst, struct gsm_trans, sms.smr_inst);
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ int rc = 0;
+
+ switch (msg_type) {
+ case GSM411_SM_RL_DATA_IND:
+ rc = gsm411_rx_rl_data(msg, gh, trans);
+ break;
+ case GSM411_SM_RL_REPORT_IND:
+ if (!gh)
+ LOGP(DLSMS, LOGL_INFO, "Release transaction on empty "
+ "report.\n");
+ else {
+ LOGP(DLSMS, LOGL_INFO, "Release transaction on RL "
+ "report.\n");
+ rc = gsm411_rx_rl_report(msg, gh, trans);
+ }
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+/* receive MNSMS sap message from SMC
+ * NOTE: Message is freed by sender
+ */
+static int gsm411_mn_recv(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg)
+{
+ struct gsm_trans *trans =
+ container_of(inst, struct gsm_trans, sms.smc_inst);
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ int rc = 0;
+
+ switch (msg_type) {
+ case GSM411_MNSMS_EST_IND:
+ case GSM411_MNSMS_DATA_IND:
+ LOGP(DLSMS, LOGL_INFO, "MNSMS-DATA/EST-IND\n");
+ rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg);
+ break;
+ case GSM411_MNSMS_ERROR_IND:
+ if (gh)
+ LOGP(DLSMS, LOGL_INFO, "MNSMS-ERROR-IND, cause %d "
+ "(%s)\n", gh->data[0],
+ get_value_string(gsm411_cp_cause_strs,
+ gh->data[0]));
+ else
+ LOGP(DLSMS, LOGL_INFO, "MNSMS-ERROR-IND, no cause\n");
+ rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg);
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+/* receive est/data message from MM layer */
+static int gsm411_mmsms_ind(int mmsms_msg, struct gsm_trans *trans,
+ struct msgb *msg)
+{
+ struct osmocom_ms *ms = trans->ms;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ int msg_type = gh->msg_type & 0xbf;
+ uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
+ /* flip */
+
+ /* pull the MMSMS header */
+ msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
+
+ LOGP(DLSMS, LOGL_INFO, "(ms %s) Received est/data '%u'\n", ms->name,
+ msg_type);
+
+ /* 5.4: For MO, if a CP-DATA is received for a new
+ * transaction, equals reception of an implicit
+ * last CP-ACK for previous transaction */
+ if (trans->sms.smc_inst.cp_state == GSM411_CPS_IDLE
+ && msg_type == GSM411_MT_CP_DATA) {
+ int i;
+ struct gsm_trans *ptrans;
+
+ /* Scan through all remote initiated transactions */
+ for (i=8; i<15; i++) {
+ if (i == transaction_id)
+ continue;
+
+ ptrans = trans_find_by_id(ms, GSM48_PDISC_SMS, i);
+ if (!ptrans)
+ continue;
+
+ LOGP(DLSMS, LOGL_INFO, "Implicit CP-ACK for "
+ "trans_id=%x\n", i);
+
+ /* Finish it for good */
+ gsm411_trans_free(ptrans);
+ }
+ }
+ return gsm411_smc_recv(&trans->sms.smc_inst, mmsms_msg, msg, msg_type);
+}
+
+/* receive message from MM layer */
+int gsm411_rcv_sms(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
+ int msg_type = mmh->msg_type;
+ int sapi = mmh->sapi;
+ struct gsm_trans *trans;
+ int rc = 0;
+
+ trans = trans_find_by_callref(ms, mmh->ref);
+ if (!trans) {
+ LOGP(DLSMS, LOGL_INFO, " -> (new transaction sapi=%d)\n", sapi);
+ trans = trans_alloc(ms, GSM48_PDISC_SMS, mmh->transaction_id,
+ mmh->ref);
+ if (!trans)
+ return -ENOMEM;
+ gsm411_smc_init(&trans->sms.smc_inst, 0, gsm411_mn_recv,
+ gsm411_mm_send);
+ gsm411_smr_init(&trans->sms.smr_inst, 0, gsm411_rl_recv,
+ gsm411_mn_send);
+ trans->sms.sapi = mmh->sapi;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "(ms %s) Received '%s' from MM\n", ms->name,
+ get_mmxx_name(msg_type));
+
+ switch (msg_type) {
+ case GSM48_MMSMS_EST_CNF:
+ rc = gsm411_smc_recv(&trans->sms.smc_inst, GSM411_MMSMS_EST_CNF,
+ msg, 0);
+ break;
+ case GSM48_MMSMS_EST_IND:
+ case GSM48_MMSMS_DATA_IND:
+ rc = gsm411_mmsms_ind(msg_type, trans, msg);
+ break;
+ case GSM48_MMSMS_REL_IND:
+ case GSM48_MMSMS_ERR_IND:
+ LOGP(DLSMS, LOGL_INFO, "MM connection released.\n");
+ trans_free(trans);
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Message unhandled.\n");
+ rc = -ENOTSUP;
+ }
+
+ return rc;
+}
+
diff --git a/Src/osmolib/src/host/layer23/src/mobile/gsm480_ss.c b/Src/osmolib/src/host/layer23/src/mobile/gsm480_ss.c
new file mode 100644
index 0000000..fda6288
--- /dev/null
+++ b/Src/osmolib/src/host/layer23/src/mobile/gsm480_ss.c
@@ -0,0 +1,1289 @@
+/*
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/bb/common/logging.h>
+#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/bb/mobile/mncc.h>
+#include <osmocom/bb/mobile/transaction.h>
+#include <osmocom/bb/mobile/gsm480_ss.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/bb/mobile/vty.h>
+#include <osmocom/gsm/protocol/gsm_04_80.h>
+#include <osmocom/gsm/gsm48.h>
+
+static uint32_t new_callref = 0x80000001;
+
+static int gsm480_to_mm(struct msgb *msg, struct gsm_trans *trans,
+ int msg_type);
+static const struct value_string gsm480_err_names[] = {
+ { GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER,
+ "UNKNOWN SUBSCRIBER" },
+ { GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER,
+ "ILLEGAL SUBSCRIBER" },
+ { GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED,
+ "BEARER SERVICE NOT PROVISIONED" },
+ { GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED,
+ "TELESERVICE NOT PROVISIONED" },
+ { GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT,
+ "ILLEGAL EQUIPMENT" },
+ { GSM0480_ERR_CODE_CALL_BARRED,
+ "CALL BARRED" },
+ { GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION,
+ "ILLEGAL SS OPERATION" },
+ { GSM0480_ERR_CODE_SS_ERROR_STATUS,
+ "SS ERROR STATUS" },
+ { GSM0480_ERR_CODE_SS_NOT_AVAILABLE,
+ "SS NOT AVAILABLE" },
+ { GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION,
+ "SS SUBSCRIPTION VIOLATION" },
+ { GSM0480_ERR_CODE_SS_INCOMPATIBILITY,
+ "SS INCOMPATIBILITY" },
+ { GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED,
+ "FACILITY NOT SUPPORTED" },
+ { GSM0480_ERR_CODE_ABSENT_SUBSCRIBER,
+ "ABSENT SUBSCRIBER" },
+ { GSM0480_ERR_CODE_SYSTEM_FAILURE,
+ "SYSTEM FAILURE" },
+ { GSM0480_ERR_CODE_DATA_MISSING,
+ "DATA MISSING" },
+ { GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE,
+ "UNEXPECTED DATA VALUE" },
+ { GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE,
+ "PW REGISTRATION FAILURE" },
+ { GSM0480_ERR_CODE_NEGATIVE_PW_CHECK,
+ "NEGATIVE PW CHECK" },
+ { GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION,
+ "NUM PW ATTEMPTS VIOLATION" },
+ { GSM0480_ERR_CODE_UNKNOWN_ALPHABET,
+ "UNKNOWN ALPHABET" },
+ { GSM0480_ERR_CODE_USSD_BUSY,
+ "USSD BUSY" },
+ { GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS,
+ "MAX MPTY PARTICIPANTS" },
+ { GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE,
+ "RESOURCES NOT AVAILABLE" },
+ {0, NULL }
+};
+
+/* taken from Wireshark */
+static const struct value_string Teleservice_vals[] = {
+ {0x00, "allTeleservices" },
+ {0x10, "allSpeechTransmissionServices" },
+ {0x11, "telephony" },
+ {0x12, "emergencyCalls" },
+ {0x20, "allShortMessageServices" },
+ {0x21, "shortMessageMT-PP" },
+ {0x22, "shortMessageMO-PP" },
+ {0x60, "allFacsimileTransmissionServices" },
+ {0x61, "facsimileGroup3AndAlterSpeech" },
+ {0x62, "automaticFacsimileGroup3" },
+ {0x63, "facsimileGroup4" },
+
+ {0x70, "allDataTeleservices" },
+ {0x80, "allTeleservices-ExeptSMS" },
+
+ {0x90, "allVoiceGroupCallServices" },
+ {0x91, "voiceGroupCall" },
+ {0x92, "voiceBroadcastCall" },
+
+ {0xd0, "allPLMN-specificTS" },
+ {0xd1, "plmn-specificTS-1" },
+ {0xd2, "plmn-specificTS-2" },
+ {0xd3, "plmn-specificTS-3" },
+ {0xd4, "plmn-specificTS-4" },
+ {0xd5, "plmn-specificTS-5" },
+ {0xd6, "plmn-specificTS-6" },
+ {0xd7, "plmn-specificTS-7" },
+ {0xd8, "plmn-specificTS-8" },
+ {0xd9, "plmn-specificTS-9" },
+ {0xda, "plmn-specificTS-A" },
+ {0xdb, "plmn-specificTS-B" },
+ {0xdc, "plmn-specificTS-C" },
+ {0xdd, "plmn-specificTS-D" },
+ {0xde, "plmn-specificTS-E" },
+ {0xdf, "plmn-specificTS-F" },
+ { 0, NULL }
+};
+
+/* taken from Wireshark */
+static const struct value_string Bearerservice_vals[] = {
+ {0x00, "allBearerServices" },
+ {0x10, "allDataCDA-Services" },
+ {0x11, "dataCDA-300bps" },
+ {0x12, "dataCDA-1200bps" },
+ {0x13, "dataCDA-1200-75bps" },
+ {0x14, "dataCDA-2400bps" },
+ {0x15, "dataCDA-4800bps" },
+ {0x16, "dataCDA-9600bps" },
+ {0x17, "general-dataCDA" },
+
+ {0x18, "allDataCDS-Services" },
+ {0x1A, "dataCDS-1200bps" },
+ {0x1C, "dataCDS-2400bps" },
+ {0x1D, "dataCDS-4800bps" },
+ {0x1E, "dataCDS-9600bps" },
+ {0x1F, "general-dataCDS" },
+
+ {0x20, "allPadAccessCA-Services" },
+ {0x21, "padAccessCA-300bps" },
+ {0x22, "padAccessCA-1200bps" },
+ {0x23, "padAccessCA-1200-75bps" },
+ {0x24, "padAccessCA-2400bps" },
+ {0x25, "padAccessCA-4800bps" },
+ {0x26, "padAccessCA-9600bps" },
+ {0x27, "general-padAccessCA" },
+
+ {0x28, "allDataPDS-Services" },
+ {0x2C, "dataPDS-2400bps" },
+ {0x2D, "dataPDS-4800bps" },
+ {0x2E, "dataPDS-9600bps" },
+ {0x2F, "general-dataPDS" },
+
+ {0x30, "allAlternateSpeech-DataCDA" },
+ {0x38, "allAlternateSpeech-DataCDS" },
+ {0x40, "allSpeechFollowedByDataCDA" },
+ {0x48, "allSpeechFollowedByDataCDS" },
+
+ {0x50, "allDataCircuitAsynchronous" },
+ {0x60, "allAsynchronousServices" },
+ {0x58, "allDataCircuitSynchronous" },
+ {0x68, "allSynchronousServices" },
+
+ {0xD0, "allPLMN-specificBS" },
+ {0xD1, "plmn-specificBS-1" },
+ {0xD2, "plmn-specificBS-2" },
+ {0xD3, "plmn-specificBS-3" },
+ {0xD4, "plmn-specificBS-4" },
+ {0xD5, "plmn-specificBS-5" },
+ {0xD6, "plmn-specificBS-6" },
+ {0xD7, "plmn-specificBS-7" },
+ {0xD8, "plmn-specificBS-8" },
+ {0xD9, "plmn-specificBS-9" },
+ {0xDA, "plmn-specificBS-A" },
+ {0xDB, "plmn-specificBS-B" },
+ {0xDC, "plmn-specificBS-C" },
+ {0xDD, "plmn-specificBS-D" },
+ {0xDE, "plmn-specificBS-E" },
+ {0xDF, "plmn-specificBS-F" },
+ { 0, NULL }
+};
+
+static int gsm480_ss_result(struct osmocom_ms *ms, const char *response,
+ uint8_t error)
+{
+ vty_notify(ms, NULL);
+ if (response) {
+ char text[256], *t = text, *s;
+
+ strncpy(text, response, sizeof(text) - 1);
+ text[sizeof(text) - 1] = '\0';
+ while ((s = strchr(text, '\r')))
+ *s = '\n';
+ while ((s = strsep(&t, "\n"))) {
+ vty_notify(ms, "Service response: %s\n", s);
+ }
+ } else if (error)
+ vty_notify(ms, "Service request failed: %s\n",
+ get_value_string(gsm480_err_names, error));
+ else
+ vty_notify(ms, "Service request failed.\n");
+
+ return 0;
+}
+
+enum {
+ GSM480_SS_ST_IDLE = 0,
+ GSM480_SS_ST_REGISTER,
+ GSM480_SS_ST_ACTIVE,
+};
+
+/*
+ * init / exit
+ */
+
+int gsm480_ss_init(struct osmocom_ms *ms)
+{
+ LOGP(DSS, LOGL_INFO, "init SS\n");
+
+ return 0;
+}
+
+int gsm480_ss_exit(struct osmocom_ms *ms)
+{
+ struct gsm_trans *trans, *trans2;
+
+ LOGP(DSS, LOGL_INFO, "exit SS processes for %s\n", ms->name);
+
+ llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
+ if (trans->protocol == GSM48_PDISC_NC_SS) {
+ LOGP(DSS, LOGL_NOTICE, "Free pendig "
+ "SS-transaction.\n");
+ trans_free(trans);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * transaction
+ */
+
+/* SS Specific transaction release.
+ * gets called by trans_free, DO NOT CALL YOURSELF!
+ */
+void _gsm480_ss_trans_free(struct gsm_trans *trans)
+{
+ if (trans->ss.msg) {
+ LOGP(DSS, LOGL_INFO, "Free pending SS request\n");
+ msgb_free(trans->ss.msg);
+ trans->ss.msg = NULL;
+ }
+ vty_notify(trans->ms, NULL);
+ vty_notify(trans->ms, "Service connection terminated.\n");
+}
+
+/* release MM connection, free transaction */
+static int gsm480_trans_free(struct gsm_trans *trans)
+{
+ struct msgb *nmsg;
+
+ /* release MM connection */
+ nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_REQ, trans->callref,
+ trans->transaction_id, 0);
+ if (!nmsg)
+ return -ENOMEM;
+ LOGP(DSS, LOGL_INFO, "Sending MMSS_REL_REQ\n");
+ gsm48_mmxx_downmsg(trans->ms, nmsg);
+
+ trans->callref = 0;
+ trans_free(trans);
+
+ return 0;
+}
+
+/*
+ * endcoding
+ */
+
+#define GSM480_ALLOC_SIZE 512+128
+#define GSM480_ALLOC_HEADROOM 128
+
+struct msgb *gsm480_msgb_alloc(void)
+{
+ return msgb_alloc_headroom(GSM480_ALLOC_SIZE, GSM480_ALLOC_HEADROOM,
+ "GSM 04.80");
+}
+
+static inline unsigned char *msgb_wrap_with_L(struct msgb *msgb)
+{
+ uint8_t *data = msgb_push(msgb, 1);
+
+ data[0] = msgb->len - 1;
+ return data;
+}
+
+/* support function taken from OpenBSC */
+static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag)
+{
+ uint8_t *data = msgb_push(msgb, 2);
+
+ data[0] = tag;
+ data[1] = msgb->len - 2;
+ return data;
+}
+
+static inline void msgb_wrap_with_TL_asn(struct msgb *msg, uint8_t tag)
+{
+ int len = msg->len;
+ uint8_t *data = msgb_push(msg, (len >= 128) ? 3 : 2);
+
+ *data++ = tag;
+ if (len >= 128)
+ *data++ = 0x81;
+ *data = len;
+ return;
+}
+
+/* support function taken from OpenBSC */
+static inline unsigned char *msgb_push_TLV1(struct msgb *msgb, uint8_t tag,
+uint8_t value)
+{
+ uint8_t *data = msgb_push(msgb, 3);
+
+ data[0] = tag;
+ data[1] = 1;
+ data[2] = value;
+ return data;
+}
+
+static const char *ss_code_by_char(const char *code, uint8_t *ss_code)
+{
+ if (!strncmp(code, "21", 2)) {
+ *ss_code = 33;
+ return code + 2;
+ }
+ if (!strncmp(code, "67", 2)) {
+ *ss_code = 41;
+ return code + 2;
+ }
+ if (!strncmp(code, "61", 2)) {
+ *ss_code = 42;
+ return code + 2;
+ }
+ if (!strncmp(code, "62", 2)) {
+ *ss_code = 43;
+ return code + 2;
+ }
+ if (!strncmp(code, "002", 3)) {
+ *ss_code = 32;
+ return code + 3;
+ }
+ if (!strncmp(code, "004", 3)) {
+ *ss_code = 40;
+ return code + 3;
+ }
+
+ return NULL;
+}
+
+static const char *decode_ss_code(uint8_t ss_code)
+{
+ static char unknown[16];
+
+ switch (ss_code) {
+ case 33:
+ return "CFU";
+ case 41:
+ return "CFB";
+ case 42:
+ return "CFNR";
+ case 43:
+ return "CF Not Reachable";
+ case 32:
+ return "All CF";
+ case 40:
+ return "All conditional CF";
+ default:
+ sprintf(unknown, "Unknown %d", ss_code);
+ return unknown;
+ }
+}
+
+static int gsm480_tx_release_compl(struct gsm_trans *trans, uint8_t cause)
+{
+ struct msgb *msg;
+ struct gsm48_hdr *gh;
+
+ msg = gsm480_msgb_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_NC_SS | (trans->transaction_id << 4);
+ gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
+
+ if (cause) {
+ uint8_t *tlv = msgb_put(msg, 4);
+ *tlv = GSM48_IE_CAUSE;
+ *tlv = 2;
+ *tlv = 0x80 | cause;
+ *tlv = 0x80 | GSM48_CAUSE_LOC_USER;
+ }
+ return gsm480_to_mm(msg, trans, GSM48_MMSS_DATA_REQ);
+}
+
+static int return_imei(struct osmocom_ms *ms)
+{
+ char text[32];
+ struct gsm_settings *set = &ms->settings;
+
+ sprintf(text, "IMEI: %s SV: %s", set->imei,
+ set->imeisv + strlen(set->imei));
+ gsm480_ss_result(ms, text, 0);
+
+ return 0;
+}
+
+/* prepend invoke-id, facility IE and facility message */
+static int gsm480_tx_invoke(struct gsm_trans *trans, struct msgb *msg,
+ uint8_t msg_type)
+{
+ struct gsm48_hdr *gh;
+
+ /* Pre-pend the invoke ID */
+ msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, trans->ss.invoke_id);
+
+ /* Wrap this up as invoke vomponent */
+ if (msg_type == GSM0480_MTYPE_FACILITY)
+ msgb_wrap_with_TL_asn(msg, GSM0480_CTYPE_RETURN_RESULT);
+ else
+ msgb_wrap_with_TL_asn(msg, GSM0480_CTYPE_INVOKE);
+
+ /* Wrap this up as facility IE */
+ if (msg_type == GSM0480_MTYPE_FACILITY)
+ msgb_wrap_with_L(msg);
+ else
+ msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY);
+
+ /* FIXME: If phase 2, we need SSVERSION to be added */
+
+ /* Push L3 header */
+ gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_NC_SS | (trans->transaction_id << 4);
+ gh->msg_type = msg_type;
+
+ if (msg_type == GSM0480_MTYPE_FACILITY) {
+ /* directly transmit data on established connection */
+ return gsm480_to_mm(msg, trans, GSM48_MMSS_DATA_REQ);
+ } else {
+ /* store header until our MM connection is established */
+ trans->ss.msg = msg;
+
+ /* request establishment */
+ msg = gsm480_msgb_alloc();
+ if (!msg) {
+ trans_free(trans);
+ return -ENOMEM;
+ }
+ return gsm480_to_mm(msg, trans, GSM48_MMSS_EST_REQ);
+ }
+}
+
+static int gsm480_tx_cf(struct gsm_trans *trans, uint8_t msg_type,
+ uint8_t op_code, uint8_t ss_code, const char *dest)
+{
+ struct msgb *msg;
+
+ /* allocate message */
+ msg = gsm480_msgb_alloc();
+ if (!msg) {
+ trans_free(trans);
+ return -ENOMEM;
+ }
+
+ if (dest) {
+ uint8_t tlv[32];
+ int rc;
+
+ /* Forwarding To address */
+ tlv[0] = 0x84;
+ tlv[2] = 0x80; /* no extension */
+ tlv[2] |= ((dest[0] == '+') ? 0x01 : 0x00) << 4; /* type */
+ tlv[2] |= 0x1; /* plan*/
+ rc = gsm48_encode_bcd_number(tlv + 1, sizeof(tlv) - 1, 1,
+ dest + (dest[0] == '+'));
+ if (rc < 0) {
+ msgb_free(msg);
+ trans_free(trans);
+ return -EINVAL;
+ }
+ memcpy(msgb_put(msg, rc + 1), tlv, rc + 1);
+ }
+
+ /* Encode ss-Code */
+ msgb_push_TLV1(msg, ASN1_OCTET_STRING_TAG, ss_code);
+
+ /* Then wrap these as a Sequence */
+ msgb_wrap_with_TL_asn(msg, GSM_0480_SEQUENCE_TAG);
+
+ /* Pre-pend the operation code */
+ msgb_push_TLV1(msg, GSM0480_OPERATION_CODE, op_code);
+
+ return gsm480_tx_invoke(trans, msg, msg_type);
+}
+
+static int gsm480_tx_ussd(struct gsm_trans *trans, uint8_t msg_type,
+ const char *text)
+{
+ struct msgb *msg;
+ int length;
+
+ /* allocate message */
+ msg = gsm480_msgb_alloc();
+ if (!msg) {
+ trans_free(trans);
+ return -ENOMEM;
+ }
+
+ /* Encode service request */
+ length = gsm_7bit_encode(msg->data, text);
+ msgb_put(msg, length);
+
+ /* Then wrap it as an Octet String */
+ msgb_wrap_with_TL_asn(msg, ASN1_OCTET_STRING_TAG);
+
+ /* Pre-pend the DCS octet string */
+ msgb_push_TLV1(msg, ASN1_OCTET_STRING_TAG, 0x0F);
+
+ /* Then wrap these as a Sequence */
+ msgb_wrap_with_TL_asn(msg, GSM_0480_SEQUENCE_TAG);
+
+ if (msg_type == GSM0480_MTYPE_FACILITY) {
+ /* Pre-pend the operation code */
+ msgb_push_TLV1(msg, GSM0480_OPERATION_CODE,
+ GSM0480_OP_CODE_USS_REQUEST);
+
+ /* Then wrap these as a Sequence */
+ msgb_wrap_with_TL_asn(msg, GSM_0480_SEQUENCE_TAG);
+ } else {
+ /* Pre-pend the operation code */
+ msgb_push_TLV1(msg, GSM0480_OPERATION_CODE,
+ GSM0480_OP_CODE_PROCESS_USS_REQ);
+ }
+
+ return gsm480_tx_invoke(trans, msg, msg_type);
+}
+
+/* create and send service code */
+int ss_send(struct osmocom_ms *ms, const char *code, int new_trans)
+{
+ struct gsm_trans *trans = NULL, *transt;
+ uint8_t transaction_id;
+
+ /* look for an old transaction */
+ if (!new_trans) {
+ llist_for_each_entry(transt, &ms->trans_list, entry) {
+ if (transt->protocol == GSM48_PDISC_NC_SS) {
+ trans = transt;
+ break;
+ }
+ }
+ }
+
+ /* if there is an old transaction, check if we can send data */
+ if (trans) {
+ if (trans->ss.state != GSM480_SS_ST_ACTIVE) {
+ LOGP(DSS, LOGL_INFO, "Pending trans not active.\n");
+ gsm480_ss_result(trans->ms, "Current service pending",
+ 0);
+ return 0;
+ }
+ if (!strcmp(code, "hangup")) {
+ gsm480_tx_release_compl(trans, 0);
+ gsm480_trans_free(trans);
+ return 0;
+ }
+ LOGP(DSS, LOGL_INFO, "Existing transaction.\n");
+ return gsm480_tx_ussd(trans, GSM0480_MTYPE_FACILITY, code);
+ }
+
+ /* do nothing, if hangup is received */
+ if (!strcmp(code, "hangup"))
+ return 0;
+
+ /* internal codes */
+ if (!strcmp(code, "*#06#")) {
+ return return_imei(ms);
+ }
+
+ /* no running, no transaction */
+ if (!ms->started || ms->shutdown) {
+ gsm480_ss_result(ms, "<phone is down>", 0);
+ return -EIO;
+ }
+
+ /* allocate transaction with dummy reference */
+ transaction_id = trans_assign_trans_id(ms, GSM48_PDISC_NC_SS,
+ 0);
+ if (transaction_id < 0) {
+ LOGP(DSS, LOGL_ERROR, "No transaction ID available\n");
+ gsm480_ss_result(ms, NULL,
+ GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE);
+ return -ENOMEM;
+ }
+ trans = trans_alloc(ms, GSM48_PDISC_NC_SS, transaction_id,
+ new_callref++);
+ if (!trans) {
+ LOGP(DSS, LOGL_ERROR, "No memory for trans\n");
+ gsm480_ss_result(ms, NULL,
+ GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE);
+ return -ENOMEM;
+ }
+
+ /* go register sent state */
+ trans->ss.state = GSM480_SS_ST_REGISTER;
+
+ /* FIXME: generate invoke ID */
+ trans->ss.invoke_id = 5;
+
+ /* interrogate */
+ if (code[0] == '*' && code[1] == '#' && code[strlen(code) - 1] == '#') {
+ uint8_t ss_code = 0;
+
+ ss_code_by_char(code + 2, &ss_code);
+ if (code)
+ return gsm480_tx_cf(trans, GSM0480_MTYPE_REGISTER,
+ GSM0480_OP_CODE_INTERROGATE_SS, ss_code, NULL);
+ } else
+ /* register / activate */
+ if (code[0] == '*' && code[strlen(code) - 1] == '#') {
+ uint8_t ss_code = 0;
+ const char *to;
+ char dest[32];
+
+ /* double star */
+ if (code[1] == '*')
+ code++;
+
+ to = ss_code_by_char(code + 1, &ss_code);
+
+ /* register */
+ if (code && to && to[0] == '*') {
+ strncpy(dest, to + 1, sizeof(dest) - 1);
+ dest[sizeof(dest) - 1] = '\0';
+ dest[strlen(dest) - 1] = '\0';
+ return gsm480_tx_cf(trans, GSM0480_MTYPE_REGISTER,
+ GSM0480_OP_CODE_REGISTER_SS, ss_code, dest);
+ }
+ /* activate */
+ if (code && to && to[0] == '#') {
+ return gsm480_tx_cf(trans, GSM0480_MTYPE_REGISTER,
+ GSM0480_OP_CODE_ACTIVATE_SS, ss_code, NULL);
+ }
+ } else
+ /* erasure */
+ if (code[0] == '#' && code[1] == '#' && code[strlen(code) - 1] == '#') {
+ uint8_t ss_code = 0;
+
+ ss_code_by_char(code + 2, &ss_code);
+
+ if (code)
+ return gsm480_tx_cf(trans, GSM0480_MTYPE_REGISTER,
+ GSM0480_OP_CODE_ERASE_SS, ss_code, NULL);
+ } else
+ /* deactivate */
+ if (code[0] == '#' && code[strlen(code) - 1] == '#') {
+ uint8_t ss_code = 0;
+
+ ss_code_by_char(code + 1, &ss_code);
+
+ if (code)
+ return gsm480_tx_cf(trans, GSM0480_MTYPE_REGISTER,
+ GSM0480_OP_CODE_DEACTIVATE_SS, ss_code, NULL);
+ }
+
+ /* other codes */
+ return gsm480_tx_ussd(trans, GSM0480_MTYPE_REGISTER, code);
+}
+
+/*
+ * decoding
+ */
+
+static int parse_tag_asn1(const uint8_t *data, int len,
+ const uint8_t **tag_data, int *tag_len)
+{
+ /* at least 2 bytes (tag + len) */
+ if (len < 2)
+ return -1;
+
+ /* extended length */
+ if (data[1] == 0x81) {
+ /* at least 2 bytes (tag + 0x81 + len) */
+ if (len < 3)
+ return -1;
+ *tag_len = data[2];
+ *tag_data = data + 3;
+ len -= 3;
+ } else {
+ *tag_len = data[1];
+ *tag_data = data + 2;
+ len -= 2;
+ }
+
+ /* check for buffer overflow */
+ if (len < *tag_len)
+ return -1;
+
+ /* return length */
+ return len;
+}
+
+static int gsm480_rx_ussd(struct gsm_trans *trans, const uint8_t *data,
+ int len)
+{
+ int num_chars;
+ char text[256];
+ int i;
+ const uint8_t *tag_data;
+ int tag_len;
+
+ /* sequence tag */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "2. Sequence tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != GSM_0480_SEQUENCE_TAG) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting 2. Sequence Tag\n");
+ return -EINVAL;
+ }
+ len = tag_len;
+ data = tag_data;
+
+ /* DSC */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 1) {
+ LOGP(DSS, LOGL_NOTICE, "DSC tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != ASN1_OCTET_STRING_TAG || tag_len != 1) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting DSC tag\n");
+ return -EINVAL;
+ }
+ if (tag_data[0] != 0x0f) {
+ LOGP(DSS, LOGL_NOTICE, "DSC not 0x0f\n");
+ return -EINVAL;
+ }
+ len -= tag_data - data + tag_len;
+ data = tag_data + tag_len;
+
+ /* text */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "Text tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != ASN1_OCTET_STRING_TAG) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting text tag\n");
+ return -EINVAL;
+ }
+ num_chars = tag_len * 8 / 7;
+ /* Prevent a mobile-originated buffer-overrun! */
+ if (num_chars > sizeof(text) - 1)
+ num_chars = sizeof(text) - 1;
+ text[sizeof(text) - 1] = '\0';
+ gsm_7bit_decode(text, tag_data, num_chars);
+
+ for (i = 0; text[i]; i++) {
+ if (text[i] == '\r')
+ text[i] = '\n';
+ }
+ /* remove last CR, if exists */
+ if (text[0] && text[strlen(text) - 1] == '\n')
+ text[strlen(text) - 1] = '\0';
+ gsm480_ss_result(trans->ms, text, 0);
+
+ return 0;
+}
+
+static int gsm480_rx_cf(struct gsm_trans *trans, const uint8_t *data,
+ int len)
+{
+ struct osmocom_ms *ms = trans->ms;
+ const uint8_t *tag_data, *data2;
+ int tag_len, len2;
+ char number[32];
+
+ LOGP(DSS, LOGL_INFO, "call forwarding reply: len %d data %s\n", len,
+ osmo_hexdump(data, len));
+
+ vty_notify(ms, NULL);
+
+ /* forwarding feature list */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "Tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] == 0x80) {
+ if ((tag_data[0] & 0x01))
+ vty_notify(ms, "Status: activated\n");
+ else
+ vty_notify(ms, "Status: deactivated\n");
+ return 0;
+ }
+
+ switch(data[0]) {
+ case 0xa3:
+ len = tag_len;
+ data = tag_data;
+ break;
+ case 0xa0: /* forwarding info */
+ len = tag_len;
+ data = tag_data;
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 1) {
+ LOGP(DSS, LOGL_NOTICE, "Tag too short\n");
+ return -EINVAL;
+ }
+ /* check for SS code */
+ if (data[0] != 0x04)
+ break;
+ vty_notify(ms, "Reply for %s\n", decode_ss_code(tag_data[0]));
+ len -= tag_data - data + tag_len;
+ data = tag_data + tag_len;
+ /* sequence tag */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "Tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != GSM_0480_SEQUENCE_TAG) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting sequence tag\n");
+ return -EINVAL;
+ }
+ len = tag_len;
+ data = tag_data;
+ break;
+ default:
+ vty_notify(ms, "Call Forwarding reply unsupported.\n");
+ return 0;
+ }
+
+ while (len) {
+ /* sequence tag */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "Tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != GSM_0480_SEQUENCE_TAG) {
+ len -= tag_data - data + tag_len;
+ data = tag_data + tag_len;
+ LOGP(DSS, LOGL_NOTICE, "Skipping tag 0x%x\n", data[0]);
+ continue;
+ }
+ len -= tag_data - data + tag_len;
+ data = tag_data + tag_len;
+ len2 = tag_len;
+ data2 = tag_data;
+
+ while (len2) {
+ /* tags in sequence */
+ if (parse_tag_asn1(data2, len2, &tag_data, &tag_len)
+ < 1) {
+ LOGP(DSS, LOGL_NOTICE, "Tag too short\n");
+ return -EINVAL;
+ }
+ LOGP(DSS, LOGL_INFO, "Tag: len %d data %s\n", tag_len,
+ osmo_hexdump(tag_data, tag_len));
+ switch (data2[0]) {
+ case 0x82:
+ vty_notify(ms, "Bearer Service: %s\n",
+ get_value_string(Bearerservice_vals,
+ tag_data[0]));
+ break;
+ case 0x83:
+ vty_notify(ms, "Teleservice: %s\n",
+ get_value_string(Teleservice_vals,
+ tag_data[0]));
+ break;
+ case 0x84:
+ if ((tag_data[0] & 0x01))
+ vty_notify(ms, "Status: activated\n");
+ else
+ vty_notify(ms, "Status: deactivated\n");
+ break;
+ case 0x85:
+ if (((tag_data[0] & 0x70) >> 4) == 1)
+ strcpy(number, "+");
+ else if (((tag_data[0] & 0x70) >> 4) == 1)
+ strcpy(number, "+");
+ else
+ number[0] = '\0';
+ gsm48_decode_bcd_number(number + strlen(number),
+ sizeof(number) - strlen(number),
+ tag_data - 1, 1);
+ vty_notify(ms, "Destination: %s\n", number);
+ break;
+ }
+ len2 -= tag_data - data2 + tag_len;
+ data2 = tag_data + tag_len;
+ }
+ }
+
+ return 0;
+}
+
+static int gsm480_rx_result(struct gsm_trans *trans, const uint8_t *data,
+ int len, int msg_type)
+{
+ const uint8_t *tag_data;
+ int tag_len;
+ int rc = 0;
+
+ LOGP(DSS, LOGL_INFO, "Result received (len %d)\n", len);
+
+ if (len && data[0] == 0x8d) {
+ LOGP(DSS, LOGL_NOTICE, "Skipping mysterious 0x8d\n");
+ len--;
+ data++;
+ }
+
+ /* invoke ID */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 1) {
+ LOGP(DSS, LOGL_NOTICE, "Invoke ID too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != GSM0480_COMPIDTAG_INVOKE_ID || tag_len != 1) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting invoke ID\n");
+ return -EINVAL;
+ }
+
+ if (msg_type == GSM0480_CTYPE_RETURN_RESULT) {
+ if (trans->ss.invoke_id != data[2]) {
+ LOGP(DSS, LOGL_NOTICE, "Invoke ID mismatch\n");
+ }
+ }
+ /* Store invoke ID, in case we wan't to send a result. */
+ trans->ss.invoke_id = tag_data[0];
+ len -= tag_data - data + tag_len;
+ data = tag_data + tag_len;
+
+ if (!len) {
+ gsm480_ss_result(trans->ms, "<no result>", 0);
+ return 0;
+ }
+
+ /* sequence tag */
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "Sequence tag too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != GSM_0480_SEQUENCE_TAG) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting Sequence Tag, trying "
+ "Operation Tag\n");
+ goto operation;
+ }
+ len = tag_len;
+ data = tag_data;
+
+ /* operation */
+operation:
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 1) {
+ LOGP(DSS, LOGL_NOTICE, "Operation too short\n");
+ return -EINVAL;
+ }
+ if (data[0] != GSM0480_OPERATION_CODE || tag_len != 1) {
+ LOGP(DSS, LOGL_NOTICE, "Expecting Operation Code\n");
+ return -EINVAL;
+ }
+ len -= tag_data - data + tag_len;
+ data = tag_data + tag_len;
+
+ switch (tag_data[0]) {
+ case GSM0480_OP_CODE_PROCESS_USS_REQ:
+ case GSM0480_OP_CODE_USS_REQUEST:
+ rc = gsm480_rx_ussd(trans, data, len);
+ break;
+ case GSM0480_OP_CODE_INTERROGATE_SS:
+ case GSM0480_OP_CODE_REGISTER_SS:
+ case GSM0480_OP_CODE_ACTIVATE_SS:
+ case GSM0480_OP_CODE_DEACTIVATE_SS:
+ case GSM0480_OP_CODE_ERASE_SS:
+ rc = gsm480_rx_cf(trans, data, len);
+ break;
+ default:
+ LOGP(DSS, LOGL_NOTICE, "Operation code not USS\n");
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+/* facility from BSC */
+static int gsm480_rx_fac_ie(struct gsm_trans *trans, const uint8_t *data,
+ int len)
+{
+ int rc = 0;
+ const uint8_t *tag_data;
+ int tag_len;
+
+ LOGP(DSS, LOGL_INFO, "Facility received (len %d)\n", len);
+
+ if (parse_tag_asn1(data, len, &tag_data, &tag_len) < 0) {
+ LOGP(DSS, LOGL_NOTICE, "Facility too short\n");
+ return -EINVAL;
+ }
+
+ switch (data[0]) {
+ case GSM0480_CTYPE_INVOKE:
+ case GSM0480_CTYPE_RETURN_RESULT:
+ rc = gsm480_rx_result(trans, tag_data, tag_len, data[0]);
+ break;
+ case GSM0480_CTYPE_RETURN_ERROR:
+ // FIXME: return error code
+ gsm480_ss_result(trans->ms, "<error received>", 0);
+ break;
+ case GSM0480_CTYPE_REJECT:
+ gsm480_ss_result(trans->ms, "<service rejected>", 0);
+ break;
+ default:
+ LOGP(DSS, LOGL_NOTICE, "CTYPE unknown\n");
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static int gsm480_rx_cause_ie(struct gsm_trans *trans, const uint8_t *data,
+ int len)
+{
+ uint8_t value;
+
+ LOGP(DSS, LOGL_INFO, "Cause received (len %d)\n", len);
+
+ if (len < 2) {
+ LOGP(DSS, LOGL_NOTICE, "Cause too short\n");
+ return -EINVAL;
+ }
+ if (!(data[1] & 0x80)) {
+ if (len < 3) {
+ LOGP(DSS, LOGL_NOTICE, "Cause too short\n");
+ return -EINVAL;
+ }
+ value = data[3] & 0x7f;
+ } else
+ value = data[2] & 0x7f;
+
+ LOGP(DSS, LOGL_INFO, "Received Cause %d\n", value);
+
+ /* this is an error */
+ return -EINVAL;
+}
+
+/* release complete from BSC */
+static int gsm480_rx_release_comp(struct gsm_trans *trans, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+ struct tlv_parsed tp;
+ int rc = 0;
+
+ tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+ if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+ rc = gsm480_rx_fac_ie(trans, TLVP_VAL(&tp, GSM48_IE_FACILITY),
+ *(TLVP_VAL(&tp, GSM48_IE_FACILITY)-1));
+ } else {
+ /* facility optional */
+ LOGP(DSS, LOGL_INFO, "No facility IE received\n");
+ if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
+ rc = gsm480_rx_cause_ie(trans,
+ TLVP_VAL(&tp, GSM48_IE_CAUSE),
+ *(TLVP_VAL(&tp, GSM48_IE_CAUSE)-1));
+ }
+ }
+
+ if (rc < 0)
+ gsm480_ss_result(trans->ms, NULL, 0);
+ if (rc > 0)
+ gsm480_ss_result(trans->ms, NULL, rc);
+
+ /* remote releases */
+ gsm480_trans_free(trans);
+
+ return rc;
+}
+
+/* facility from BSC */
+static int gsm480_rx_facility(struct gsm_trans *trans, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+ struct tlv_parsed tp;
+ int rc = 0;
+
+ /* go register state */
+ trans->ss.state = GSM480_SS_ST_ACTIVE;
+
+ tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
+ GSM48_IE_FACILITY, 0);
+ if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+ rc = gsm480_rx_fac_ie(trans, TLVP_VAL(&tp, GSM48_IE_FACILITY),
+ *(TLVP_VAL(&tp, GSM48_IE_FACILITY)-1));
+ } else {
+ LOGP(DSS, LOGL_INFO, "No facility IE received\n");
+ /* release 3.7.5 */
+ gsm480_tx_release_compl(trans, 96);
+ /* local releases */
+ gsm480_trans_free(trans);
+ }
+
+ if (rc < 0)
+ gsm480_ss_result(trans->ms, NULL, 0);
+ if (rc > 0)
+ gsm480_ss_result(trans->ms, NULL, rc);
+
+ return rc;
+}
+
+/* regisster from BSC */
+static int gsm480_rx_register(struct gsm_trans *trans, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+ struct tlv_parsed tp;
+ int rc = 0;
+
+ /* go register state */
+ trans->ss.state = GSM480_SS_ST_ACTIVE;
+
+ tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+ if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+ rc = gsm480_rx_fac_ie(trans, TLVP_VAL(&tp, GSM48_IE_FACILITY),
+ *(TLVP_VAL(&tp, GSM48_IE_FACILITY)-1));
+ } else {
+ /* facility optional */
+ LOGP(DSS, LOGL_INFO, "No facility IE received\n");
+ /* release 3.7.5 */
+ gsm480_tx_release_compl(trans, 96);
+ /* local releases */
+ gsm480_trans_free(trans);
+ }
+
+ if (rc < 0)
+ gsm480_ss_result(trans->ms, NULL, 0);
+ if (rc > 0)
+ gsm480_ss_result(trans->ms, NULL, rc);
+
+ return rc;
+}
+
+/*
+ * message handling
+ */
+
+/* push MMSS header and send to MM */
+static int gsm480_to_mm(struct msgb *msg, struct gsm_trans *trans,
+ int msg_type)
+{
+ struct gsm48_mmxx_hdr *mmh;
+
+ /* set l3H */
+ msg->l3h = msg->data;
+
+ /* push RR header */
+ msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
+ mmh = (struct gsm48_mmxx_hdr *)msg->data;
+ mmh->msg_type = msg_type;
+ mmh->ref = trans->callref;
+ mmh->transaction_id = trans->transaction_id;
+ mmh->sapi = 0;
+ mmh->emergency = 0;
+
+ /* send message to MM */
+ LOGP(DSS, LOGL_INFO, "Sending '%s' to MM (callref=%x, "
+ "transaction_id=%d)\n", get_mmxx_name(msg_type), trans->callref,
+ trans->transaction_id);
+ return gsm48_mmxx_downmsg(trans->ms, msg);
+}
+
+/* receive est confirm from MM layer */
+static int gsm480_mmss_est(int mmss_msg, struct gsm_trans *trans,
+ struct msgb *msg)
+{
+ struct osmocom_ms *ms = trans->ms;
+ struct msgb *temp;
+
+ LOGP(DSS, LOGL_INFO, "(ms %s) Received confirm, sending pending SS\n",
+ ms->name);
+
+ /* remove transaction, if no SS message */
+ if (!trans->ss.msg) {
+ LOGP(DSS, LOGL_ERROR, "(ms %s) No pending SS!\n", ms->name);
+ gsm480_trans_free(trans);
+ return -EINVAL;
+ }
+
+ /* detach message and then send */
+ temp = trans->ss.msg;
+ trans->ss.msg = NULL;
+ return gsm480_to_mm(temp, trans, GSM48_MMSS_DATA_REQ);
+}
+
+/* receive data indication from MM layer */
+static int gsm480_mmss_ind(int mmss_msg, struct gsm_trans *trans,
+ struct msgb *msg)
+{
+ struct osmocom_ms *ms = trans->ms;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ int msg_type = gh->msg_type & 0xbf;
+ int rc = 0;
+
+ /* pull the MMSS header */
+ msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
+
+ LOGP(DSS, LOGL_INFO, "(ms %s) Received est/data '%u'\n", ms->name,
+ msg_type);
+
+ switch (msg_type) {
+ case GSM0480_MTYPE_RELEASE_COMPLETE:
+ rc = gsm480_rx_release_comp(trans, msg);
+ break;
+ case GSM0480_MTYPE_FACILITY:
+ rc = gsm480_rx_facility(trans, msg);
+ break;
+ case GSM0480_MTYPE_REGISTER:
+ rc = gsm480_rx_register(trans, msg);
+ break;
+ default:
+ LOGP(DSS, LOGL_NOTICE, "Message unhandled.\n");
+ /* release 3.7.4 */
+ gsm480_tx_release_compl(trans, 97);
+ gsm480_trans_free(trans);
+ rc = -ENOTSUP;
+ }
+ return 0;
+}
+
+/* receive message from MM layer */
+int gsm480_rcv_ss(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
+ int msg_type = mmh->msg_type;
+ struct gsm_trans *trans;
+ int rc = 0;
+
+ trans = trans_find_by_callref(ms, mmh->ref);
+ if (!trans) {
+ LOGP(DSS, LOGL_INFO, " -> (new transaction)\n");
+ trans = trans_alloc(ms, GSM48_PDISC_NC_SS, mmh->transaction_id,
+ mmh->ref);
+ if (!trans)
+ return -ENOMEM;
+ }
+
+ LOGP(DSS, LOGL_INFO, "(ms %s) Received '%s' from MM\n", ms->name,
+ get_mmxx_name(msg_type));
+
+ switch (msg_type) {
+ case GSM48_MMSS_EST_CNF:
+ rc = gsm480_mmss_est(msg_type, trans, msg);
+ break;
+ case GSM48_MMSS_EST_IND:
+ case GSM48_MMSS_DATA_IND:
+ rc = gsm480_mmss_ind(msg_type, trans, msg);
+ break;
+ case GSM48_MMSS_REL_IND:
+ case GSM48_MMSS_ERR_IND:
+ LOGP(DSS, LOGL_INFO, "MM connection released.\n");
+ trans_free(trans);
+ break;
+ default:
+ LOGP(DSS, LOGL_NOTICE, "Message unhandled.\n");
+ rc = -ENOTSUP;
+ }
+
+ return rc;
+}
+
diff --git a/Src/osmolib/src/host/layer23/src/mobile/gsm48_cc.c b/Src/osmolib/src/host/layer23/src/mobile/gsm48_cc.c
index 2e97819..38dfab0 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/gsm48_cc.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/gsm48_cc.c
@@ -43,7 +43,7 @@ extern void *l23_ctx;
static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
static int gsm48_rel_null_free(struct gsm_trans *trans);
int mncc_release_ind(struct osmocom_ms *ms, struct gsm_trans *trans,
- u_int32_t callref, int location, int value);
+ uint32_t callref, int location, int value);
static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);
static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg);
@@ -173,6 +173,7 @@ static int gsm48_cc_to_mm(struct msgb *msg, struct gsm_trans *trans,
mmh->msg_type = msg_type;
mmh->ref = trans->callref;
mmh->transaction_id = trans->transaction_id;
+ mmh->sapi = 0;
mmh->emergency = emergency;
/* send message to MM */
@@ -215,7 +216,7 @@ int mncc_dequeue(struct osmocom_ms *ms)
struct gsm_mncc *mncc;
struct msgb *msg;
int work = 0;
-
+
while ((msg = msgb_dequeue(&cc->mncc_upqueue))) {
mncc = (struct gsm_mncc *)msg->data;
if (ms->mncc_entity.mncc_recv)
@@ -223,7 +224,7 @@ int mncc_dequeue(struct osmocom_ms *ms)
work = 1; /* work done */
msgb_free(msg);
}
-
+
return work;
}
@@ -392,7 +393,7 @@ static int gsm48_rel_null_free(struct gsm_trans *trans)
/* release MM connection */
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, trans->callref,
- trans->transaction_id);
+ trans->transaction_id, 0);
if (!nmsg)
return -ENOMEM;
LOGP(DCC, LOGL_INFO, "Sending MMCC_REL_REQ\n");
@@ -416,7 +417,7 @@ void mncc_set_cause(struct gsm_mncc *data, int loc, int val)
/* send release indication to upper layer */
int mncc_release_ind(struct osmocom_ms *ms, struct gsm_trans *trans,
- u_int32_t callref, int location, int value)
+ uint32_t callref, int location, int value)
{
struct gsm_mncc rel;
@@ -497,7 +498,7 @@ static int gsm48_cc_init_mm(struct gsm_trans *trans, void *arg)
/* establish MM connection */
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_REQ, trans->callref,
- trans->transaction_id);
+ trans->transaction_id, 0);
if (!nmsg)
return -ENOMEM;
nmmh = (struct gsm48_mmxx_hdr *) nmsg->data;
@@ -514,7 +515,7 @@ static int gsm48_cc_abort_mm(struct gsm_trans *trans, void *arg)
/* abort MM connection */
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, trans->callref,
- trans->transaction_id);
+ trans->transaction_id, 0);
if (!nmsg)
return -ENOMEM;
LOGP(DCC, LOGL_INFO, "Sending MMCC_REL_REQ\n");
@@ -556,7 +557,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans)
trans_free(trans);
return rc;
}
-
+
/* Get free transaction_id */
transaction_id = trans_assign_trans_id(trans->ms, GSM48_PDISC_CC, 0);
if (transaction_id < 0) {
@@ -712,7 +713,7 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
struct tlv_parsed tp;
struct gsm_mncc alerting;
-
+
LOGP(DCC, LOGL_INFO, "received ALERTING\n");
gsm48_stop_cc_timer(trans);
@@ -945,7 +946,7 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
gsm48_encode_ssversion(nmsg, &alerting->ssversion);
new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
-
+
return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
}
@@ -993,7 +994,7 @@ static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
gsm48_stop_cc_timer(trans);
new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
+
memset(&connect_ack, 0, sizeof(struct gsm_mncc));
connect_ack.callref = trans->callref;
return mncc_recvmsg(trans->ms, trans, MNCC_SETUP_COMPL_IND,
@@ -1846,7 +1847,7 @@ static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
/* state trasitions for MNCC messages (upper layer) */
static struct downstate {
- u_int32_t states;
+ uint32_t states;
int type;
int (*rout) (struct gsm_trans *trans, void *arg);
} downstatelist[] = {
@@ -1991,12 +1992,12 @@ int mncc_tx_to_cc(void *inst, int msg_type, void *arg)
if ((msg_type == downstatelist[i].type)
&& ((1 << trans->cc.state) & downstatelist[i].states))
break;
- if (i == DOWNSLLEN) {
- LOGP(DCC, LOGL_NOTICE, "Message %d unhandled at state "
- "%d\n", msg_type, trans->cc.state);
- return 0;
- }
-
+ if (i == DOWNSLLEN) {
+ LOGP(DCC, LOGL_NOTICE, "Message %d unhandled at state %d\n",
+ msg_type, trans->cc.state);
+ return 0;
+ }
+
rc = downstatelist[i].rout(trans, arg);
return rc;
@@ -2004,7 +2005,7 @@ int mncc_tx_to_cc(void *inst, int msg_type, void *arg)
/* state trasitions for call control messages (lower layer) */
static struct datastate {
- u_int32_t states;
+ uint32_t states;
int type;
int (*rout) (struct gsm_trans *trans, struct msgb *msg);
} datastatelist[] = {
@@ -2021,7 +2022,7 @@ static struct datastate {
GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
- SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.6 */
+ SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.6 */
GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
/* mobile terminating call establishment */
diff --git a/Src/osmolib/src/host/layer23/src/mobile/gsm48_mm.c b/Src/osmolib/src/host/layer23/src/mobile/gsm48_mm.c
index ff936e3..a8f699d 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/gsm48_mm.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/gsm48_mm.c
@@ -36,6 +36,8 @@
#include <osmocom/bb/common/networks.h>
#include <osmocom/bb/common/l1ctl.h>
#include <osmocom/bb/mobile/gsm48_cc.h>
+#include <osmocom/bb/mobile/gsm480_ss.h>
+#include <osmocom/bb/mobile/gsm411_sms.h>
#include <osmocom/bb/mobile/app_mobile.h>
#include <osmocom/bb/mobile/vty.h>
@@ -661,7 +663,7 @@ const char *get_mmr_name(int value)
/* allocate GSM 04.08 message (MMxx-SAP) */
struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
- uint8_t transaction_id)
+ uint8_t transaction_id, uint8_t sapi)
{
struct msgb *msg;
struct gsm48_mmxx_hdr *mmh;
@@ -675,6 +677,7 @@ struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
mmh->msg_type = msg_type;
mmh->ref = ref;
mmh->transaction_id = transaction_id;
+ mmh->sapi = sapi;
return msg;
}
@@ -748,26 +751,24 @@ int gsm48_mmxx_dequeue(struct osmocom_ms *ms)
struct msgb *msg;
struct gsm48_mmxx_hdr *mmh;
int work = 0;
-
+
while ((msg = msgb_dequeue(&mm->mmxx_upqueue))) {
mmh = (struct gsm48_mmxx_hdr *) msg->data;
switch (mmh->msg_type & GSM48_MMXX_MASK) {
case GSM48_MMCC_CLASS:
gsm48_rcv_cc(ms, msg);
break;
-#if 0
case GSM48_MMSS_CLASS:
- gsm48_rcv_ss(ms, msg);
+ gsm480_rcv_ss(ms, msg);
break;
case GSM48_MMSMS_CLASS:
- gsm48_rcv_sms(ms, msg);
+ gsm411_rcv_sms(ms, msg);
break;
-#endif
}
msgb_free(msg);
work = 1; /* work done */
}
-
+
return work;
}
@@ -778,14 +779,14 @@ int gsm48_mmr_dequeue(struct osmocom_ms *ms)
struct msgb *msg;
struct gsm48_mmr *mmr;
int work = 0;
-
+
while ((msg = msgb_dequeue(&mm->mmr_downqueue))) {
mmr = (struct gsm48_mmr *) msg->data;
gsm48_rcv_mmr(ms, msg);
msgb_free(msg);
work = 1; /* work done */
}
-
+
return work;
}
@@ -795,13 +796,13 @@ int gsm48_rr_dequeue(struct osmocom_ms *ms)
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct msgb *msg;
int work = 0;
-
+
while ((msg = msgb_dequeue(&mm->rr_upqueue))) {
/* msg is freed there */
gsm48_rcv_rr(ms, msg);
work = 1; /* work done */
}
-
+
return work;
}
@@ -812,20 +813,20 @@ int gsm48_mmevent_dequeue(struct osmocom_ms *ms)
struct gsm48_mm_event *mme;
struct msgb *msg;
int work = 0;
-
+
while ((msg = msgb_dequeue(&mm->event_queue))) {
mme = (struct gsm48_mm_event *) msg->data;
gsm48_mm_ev(ms, mme->msg_type, msg);
msgb_free(msg);
work = 1; /* work done */
}
-
+
return work;
}
/* push RR header and send to RR */
-static int gsm48_mm_to_rr(struct osmocom_ms *ms, struct msgb *msg,
- int msg_type, uint8_t cause)
+static int gsm48_mm_to_rr(struct osmocom_ms *ms, struct msgb *msg, int msg_type,
+ uint8_t sapi, uint8_t cause)
{
struct gsm48_rr_hdr *rrh;
@@ -833,6 +834,7 @@ static int gsm48_mm_to_rr(struct osmocom_ms *ms, struct msgb *msg,
msgb_push(msg, sizeof(struct gsm48_rr_hdr));
rrh = (struct gsm48_rr_hdr *) msg->data;
rrh->msg_type = msg_type;
+ rrh->sapi = sapi;
rrh->cause = cause;
/* send message to RR */
@@ -927,7 +929,7 @@ static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate)
switch (substate) {
case GSM48_MM_SST_NORMAL_SERVICE:
vty_notify(ms, NULL);
- vty_notify(ms, "On Network, normal service: %s, %s\n",
+ vty_notify(ms, "On Network, normal service: %s, %s\n",
gsm_get_mcc(plmn->mcc),
gsm_get_mnc(plmn->mcc, plmn->mnc));
break;
@@ -1117,8 +1119,9 @@ static int gsm48_mm_return_idle(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
- /* selected cell equals the registered LAI */
- if (subscr->lac /* valid */
+ /* if we are attached and selected cell equals the registered LAI */
+ if (subscr->imsi_attached
+ && subscr->lac /* valid */
&& cs->sel_mcc == subscr->mcc
&& cs->sel_mnc == subscr->mnc
&& cs->sel_lac == subscr->lac) {
@@ -1336,7 +1339,7 @@ int gsm48_mm_exit(struct osmocom_ms *ms)
/* flush lists */
while (!llist_empty(&mm->mm_conn)) {
- conn = llist_entry(mm->mm_conn.next,
+ conn = llist_entry(mm->mm_conn.next,
struct gsm48_mm_conn, list);
mm_conn_free(conn);
}
@@ -1348,7 +1351,7 @@ int gsm48_mm_exit(struct osmocom_ms *ms)
msgb_free(msg);
while ((msg = msgb_dequeue(&mm->event_queue)))
msgb_free(msg);
-
+
/* stop timers */
stop_mm_t3210(mm);
stop_mm_t3211(mm);
@@ -1413,7 +1416,7 @@ struct gsm48_mm_conn *mm_conn_by_ref(struct gsm48_mmlayer *mm,
/* create MM connection instance */
static struct gsm48_mm_conn* mm_conn_new(struct gsm48_mmlayer *mm,
- int proto, uint8_t transaction_id, uint32_t ref)
+ int proto, uint8_t transaction_id, uint8_t sapi, uint32_t ref)
{
struct gsm48_mm_conn *conn = talloc_zero(l23_ctx, struct gsm48_mm_conn);
@@ -1421,12 +1424,13 @@ static struct gsm48_mm_conn* mm_conn_new(struct gsm48_mmlayer *mm,
return NULL;
LOGP(DMM, LOGL_INFO, "New MM Connection (proto 0x%02x trans_id %d "
- "ref %d)\n", proto, transaction_id, ref);
+ "sapi %d ref %x)\n", proto, transaction_id, sapi, ref);
conn->mm = mm;
conn->state = GSM48_MMXX_ST_IDLE;
conn->transaction_id = transaction_id;
conn->protocol = proto;
+ conn->sapi = sapi;
conn->ref = ref;
llist_add(&conn->list, &mm->mm_conn);
@@ -1448,22 +1452,27 @@ void mm_conn_free(struct gsm48_mm_conn *conn)
/* support function to release pending/all ongoing MM connections */
static int gsm48_mm_release_mm_conn(struct osmocom_ms *ms, int abort_any,
- uint8_t cause, int error)
+ uint8_t cause, int error, uint8_t sapi)
{
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct gsm48_mm_conn *conn, *conn2;
struct msgb *nmsg;
struct gsm48_mmxx_hdr *nmmh;
+ /* Note: For SAPI 0 all connections are released */
+
if (abort_any)
- LOGP(DMM, LOGL_INFO, "Release any MM Connection\n");
+ LOGP(DMM, LOGL_INFO, "Release any MM Connection "
+ "(sapi = %d)\n", sapi);
else
- LOGP(DMM, LOGL_INFO, "Release pending MM Connections\n");
+ LOGP(DMM, LOGL_INFO, "Release pending MM Connections "
+ "(sapi = %d)\n", sapi);
/* release MM connection(s) */
llist_for_each_entry_safe(conn, conn2, &mm->mm_conn, list) {
/* abort any OR the pending connection */
- if (abort_any || conn->state == GSM48_MMXX_ST_CONN_PEND) {
+ if ((abort_any || conn->state == GSM48_MMXX_ST_CONN_PEND)
+ && (sapi == conn->sapi || sapi == 0)) {
/* send MMxx-REL-IND */
nmsg = NULL;
switch(conn->protocol) {
@@ -1471,19 +1480,22 @@ static int gsm48_mm_release_mm_conn(struct osmocom_ms *ms, int abort_any,
nmsg = gsm48_mmxx_msgb_alloc(
error ? GSM48_MMCC_ERR_IND
: GSM48_MMCC_REL_IND, conn->ref,
- conn->transaction_id);
+ conn->transaction_id,
+ conn->sapi);
break;
case GSM48_PDISC_NC_SS:
nmsg = gsm48_mmxx_msgb_alloc(
error ? GSM48_MMSS_ERR_IND
: GSM48_MMSS_REL_IND, conn->ref,
- conn->transaction_id);
+ conn->transaction_id,
+ conn->sapi);
break;
case GSM48_PDISC_SMS:
nmsg = gsm48_mmxx_msgb_alloc(
error ? GSM48_MMSMS_ERR_IND
: GSM48_MMSMS_REL_IND, conn->ref,
- conn->transaction_id);
+ conn->transaction_id,
+ conn->sapi);
break;
}
if (!nmsg) {
@@ -1525,7 +1537,7 @@ static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, uint8_t cause)
*reject_cause = cause;
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0, 0);
}
/* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */
@@ -1545,7 +1557,7 @@ static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms)
ngh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL;
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0, 0);
}
/* 4.3.1 TMSI REALLOCATION COMMAND is received */
@@ -1661,7 +1673,7 @@ static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct msgb *msg)
memcpy(sres, mme->sres, 4);
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0, 0);
}
/* 4.3.2.5 AUTHENTICATION REJECT is received */
@@ -1766,7 +1778,7 @@ static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, uint8_t mi_type)
gsm48_encode_mi(buf, nmsg, ms, mi_type);
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0, 0);
}
/* 4.3.4.1 sending IMSI DETACH INDICATION message */
@@ -1814,7 +1826,7 @@ static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim)
/* push RR header and send down */
mm->est_cause = RR_EST_CAUSE_OTHER_SDCCH;
- return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
+ return gsm48_mm_to_rr(ms, nmsg, rr_prim, 0, mm->est_cause);
}
/* detach has ended */
@@ -1829,7 +1841,6 @@ static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg)
/* stop IMSI detach timer (if running) */
stop_mm_t3220(mm);
-
/* SIM invalid */
subscr->sim_valid = 0;
@@ -1856,6 +1867,24 @@ static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg)
return gsm48_mm_return_idle(ms, NULL);
}
+/* abort radio connection */
+static int gsm48_mm_imsi_detach_abort(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct msgb *nmsg;
+ struct gsm48_rr_hdr *nrrh;
+
+ /* abort RR if timer fired */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *) nmsg->data;
+ nrrh->cause = GSM48_RR_CAUSE_NORMAL;
+ gsm48_rr_downmsg(ms, nmsg);
+
+ /* imsi detach has ended now */
+ return gsm48_mm_imsi_detach_end(ms, msg);
+}
+
/* start an IMSI detach in MM IDLE */
static int gsm48_mm_imsi_detach_start(struct osmocom_ms *ms, struct msgb *msg)
{
@@ -1891,7 +1920,7 @@ static int gsm48_mm_imsi_detach_sent(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
-
+
/* release MM connection and proceed with IMSI detach */
static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg)
{
@@ -1903,7 +1932,7 @@ static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg)
stop_mm_t3230(mm);
/* release all connections */
- gsm48_mm_release_mm_conn(ms, 1, 16, 0);
+ gsm48_mm_release_mm_conn(ms, 1, 16, 0, 0);
/* wait for release of RR */
if (!s->att_allowed || !subscr->imsi_attached) {
@@ -1972,10 +2001,10 @@ static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
/* stop MM connection timer */
stop_mm_t3230(mm);
- gsm48_mm_release_mm_conn(ms, 1, 16, 0);
+ gsm48_mm_release_mm_conn(ms, 1, 16, 0, 0);
}
- if (reject_cause == GSM48_REJECT_ILLEGAL_ME) {
+ if (reject_cause == GSM48_REJECT_ILLEGAL_ME) {
/* SIM invalid */
subscr->sim_valid = 0;
@@ -2038,7 +2067,7 @@ static int gsm48_mm_sysinfo(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
- /* t3212 not changed in these states */
+ /* t3212 not changed in these states */
if (mm->state == GSM48_MM_ST_MM_IDLE
&& (mm->substate == GSM48_MM_SST_NO_CELL_AVAIL
|| mm->substate == GSM48_MM_SST_LIMITED_SERVICE
@@ -2074,7 +2103,7 @@ static int gsm48_mm_sysinfo(struct osmocom_ms *ms, struct msgb *msg)
}
mm->t3212_value = s->t3212;
}
-
+
return 0;
}
@@ -2095,7 +2124,7 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
struct gsm_settings *set = &ms->settings;
struct msgb *nmsg;
int msg_type;
-
+
/* (re)start only if we still require location update */
if (!mm->lupd_pending) {
LOGP(DMM, LOGL_INFO, "No loc. upd. pending.\n");
@@ -2315,7 +2344,7 @@ static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
/* location updating type */
nlu->type = mm->lupd_type;
/* cipering key */
- nlu->key_seq = subscr->key_seq;
+ nlu->key_seq = gsm_subscr_get_key_seq(ms, subscr);
/* LAI (last SIM stored LAI)
*
* NOTE: The TMSI is only valid within a LAI!
@@ -2343,7 +2372,7 @@ static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
/* push RR header and send down */
mm->est_cause = RR_EST_CAUSE_LOC_UPD;
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ, mm->est_cause);
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ, 0, mm->est_cause);
}
/* 4.4.4.1 RR is esablised during location update */
@@ -2511,7 +2540,7 @@ static int gsm48_mm_rx_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
start_mm_t3240(mm);
new_mm_state(mm, GSM48_MM_ST_LOC_UPD_REJ, 0);
-
+
return 0;
}
@@ -2522,7 +2551,7 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
struct gsm_subscriber *subscr = &ms->subscr;
struct msgb *nmsg;
struct gsm322_msg *ngm;
-
+
LOGP(DMM, LOGL_INFO, "Loc. upd. rejected (cause %d)\n",
mm->lupd_rej_cause);
@@ -2777,7 +2806,7 @@ static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
/* type and key */
nsr->cm_service_type = cm_serv;
- nsr->cipher_key_seq = subscr->key_seq;
+ nsr->cipher_key_seq = gsm_subscr_get_key_seq(ms, subscr);
/* classmark 2 */
cm2lv[0] = sizeof(struct gsm48_classmark2);
gsm48_rr_enc_cm2(ms, (struct gsm48_classmark2 *)(cm2lv + 1),
@@ -2807,7 +2836,7 @@ static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
/* prio is optional for eMLPP */
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
+ return gsm48_mm_to_rr(ms, nmsg, rr_prim, 0, mm->est_cause);
}
/* cm service abort message from upper layer
@@ -2829,7 +2858,7 @@ static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms)
ngh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0, 0);
}
/* cm service acknowledge is received from lower layer */
@@ -2900,7 +2929,7 @@ static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg)
}
/* release MM connection(s) */
- gsm48_mm_release_mm_conn(ms, abort_any, 16, 0);
+ gsm48_mm_release_mm_conn(ms, abort_any, 16, 0, 0);
/* state depends on the existance of remaining MM connections */
if (llist_empty(&mm->mm_conn))
@@ -2930,6 +2959,7 @@ static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
struct msgb *nmsg;
struct gsm48_mmxx_hdr *nmmh;
struct gsm48_mm_conn *conn, *conn_found = NULL;
+ uint8_t sapi = mmh->sapi;
/* reset loc. upd. counter on CM service request */
mm->lupd_attempt = 0;
@@ -2947,20 +2977,24 @@ static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
LOGP(DMM, LOGL_INFO, "Init MM Connection, but already have "
"pending MM Connection.\n");
cause = 17;
+ /* use sapi from connection. if no connection, use sapi from
+ * message.
+ */
+ sapi = conn_found->sapi;
reject:
nmsg = NULL;
switch(msg_type) {
case GSM48_MMCC_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND,
- mmh->ref, mmh->transaction_id);
+ mmh->ref, mmh->transaction_id, sapi);
break;
case GSM48_MMSS_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND,
- mmh->ref, mmh->transaction_id);
+ mmh->ref, mmh->transaction_id, sapi);
break;
case GSM48_MMSMS_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND,
- mmh->ref, mmh->transaction_id);
+ mmh->ref, mmh->transaction_id, sapi);
break;
}
if (!nmsg)
@@ -3039,7 +3073,7 @@ static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
}
/* create MM connection instance */
- conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->ref);
+ conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->sapi, mmh->ref);
if (!conn)
return -ENOMEM;
@@ -3166,6 +3200,7 @@ static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
int msg_type = mmh->msg_type;
+ int sapi = mmh->sapi;
struct msgb *nmsg;
struct gsm48_mmxx_hdr *nmmh;
@@ -3174,15 +3209,15 @@ static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
switch(msg_type) {
case GSM48_MMCC_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND, mmh->ref,
- mmh->transaction_id);
+ mmh->transaction_id, sapi);
break;
case GSM48_MMSS_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND, mmh->ref,
- mmh->transaction_id);
+ mmh->transaction_id, sapi);
break;
case GSM48_MMSMS_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND, mmh->ref,
- mmh->transaction_id);
+ mmh->transaction_id, sapi);
break;
}
if (!nmsg)
@@ -3198,7 +3233,7 @@ static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
*
* this function is called:
* - when ciphering command is received
- * - when cm service is accepted
+ * - when cm service is accepted
*/
static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms)
{
@@ -3228,22 +3263,33 @@ static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms)
nmsg = NULL;
switch(conn_found->protocol) {
case GSM48_PDISC_CC:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_CNF, conn->ref,
- conn->transaction_id);
+ nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_CNF,
+ conn_found->ref, conn_found->transaction_id,
+ conn_found->sapi);
break;
case GSM48_PDISC_NC_SS:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_EST_CNF, conn->ref,
- conn->transaction_id);
+ nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_EST_CNF,
+ conn_found->ref, conn_found->transaction_id,
+ conn_found->sapi);
break;
case GSM48_PDISC_SMS:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_EST_CNF, conn->ref,
- conn->transaction_id);
+ if (!mm->sapi3_link) {
+ LOGP(DMM, LOGL_INFO, "Sapi 3 link down, requesting "
+ "link, waiting for confirm.\n");
+ nmsg = gsm48_l3_msgb_alloc();
+ if (!nmsg)
+ return -ENOMEM;
+ return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ,
+ conn_found->sapi, 0);
+ }
+ nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_EST_CNF,
+ conn_found->ref, conn_found->transaction_id,
+ conn_found->sapi);
break;
}
if (!nmsg)
return -ENOMEM;
nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = 17;
gsm48_mmxx_upmsg(ms, nmsg);
return 0;
@@ -3287,13 +3333,12 @@ static int gsm48_mm_sync_ind_active(struct osmocom_ms *ms, struct msgb *msg)
switch(conn->protocol) {
case GSM48_PDISC_CC:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_SYNC_IND,
- conn->ref, conn->transaction_id);
+ conn->ref, conn->transaction_id, conn->sapi);
break;
}
if (!nmsg)
continue; /* skip if not of CC type */
nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = 17;
/* copy L3 message */
nmsg->l3h = msgb_put(nmsg, msgb_l3len(msg));
memcpy(nmsg->l3h, msg->l3h, msgb_l3len(msg));
@@ -3331,7 +3376,7 @@ static int gsm48_mm_abort_mm_con(struct osmocom_ms *ms, struct msgb *msg)
stop_mm_t3230(mm);
/* release all connections */
- gsm48_mm_release_mm_conn(ms, 1, cause, 1);
+ gsm48_mm_release_mm_conn(ms, 1, cause, 1, 0);
/* return to MM IDLE */
return gsm48_mm_return_idle(ms, NULL);
@@ -3343,7 +3388,7 @@ static int gsm48_mm_timeout_mm_con(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_mmlayer *mm = &ms->mmlayer;
/* release pending connection */
- gsm48_mm_release_mm_conn(ms, 0, 102, 0);
+ gsm48_mm_release_mm_conn(ms, 0, 102, 0, 0);
/* state depends on the existance of remaining MM connections */
if (llist_empty(&mm->mm_conn)) {
@@ -3397,12 +3442,15 @@ static int gsm48_mm_data(struct osmocom_ms *ms, struct msgb *msg)
/* mirror message with REL_IND + cause */
return gsm48_mmxx_upmsg(ms, msg);
}
-
+
+ /* set SAPI, if upper layer does not do it correctly */
+ mmh->sapi = conn->sapi;
+
/* pull MM header */
msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
/* push RR header and send down */
- return gsm48_mm_to_rr(ms, msg, GSM48_RR_DATA_REQ, 0);
+ return gsm48_mm_to_rr(ms, msg, GSM48_RR_DATA_REQ, conn->sapi, 0);
}
/* release of MM connection (active state) */
@@ -3526,6 +3574,50 @@ static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct msgb *msg)
}
/*
+ * sapi 3
+ */
+
+static int gsm48_rcv_rr_sapi3(struct osmocom_ms *ms, struct msgb *msg,
+ int msg_type, uint8_t sapi)
+{
+ struct gsm48_mmlayer *mm = &ms->mmlayer;
+ struct gsm48_mm_conn *conn;
+
+ switch (msg_type) {
+ case GSM48_RR_EST_CNF:
+ LOGP(DMM, LOGL_INFO, "SAPI 3 link up, confirming conns.\n");
+ mm->sapi3_link = 1;
+ /* indicate establishment to sapi 3 connections */
+ llist_for_each_entry(conn, &mm->mm_conn, list) {
+ if (conn->sapi == sapi
+ && conn->state == GSM48_MMXX_ST_DEDICATED) {
+ struct gsm48_mmxx_hdr *nmmh;
+ struct msgb *nmsg;
+
+ nmsg = gsm48_mmxx_msgb_alloc(
+ GSM48_MMSMS_EST_CNF, conn->ref,
+ conn->transaction_id, conn->sapi);
+ if (!nmsg)
+ return -ENOMEM;
+ nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
+ gsm48_mmxx_upmsg(ms, nmsg);
+ }
+ }
+ break;
+ case GSM48_RR_DATA_IND:
+ return gsm48_mm_data_ind(ms, msg);
+ case GSM48_RR_REL_IND:
+ LOGP(DMM, LOGL_INFO, "SAPI 3 link down, releasing conns.\n");
+ mm->sapi3_link = 0;
+ gsm48_mm_release_mm_conn(ms, 1, 16, 0, sapi);
+ break;
+ }
+ msgb_free(msg);
+
+ return 0;
+}
+
+/*
* state machines
*/
@@ -3802,11 +3894,15 @@ static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
int msg_type = rrh->msg_type;
+ int sapi = rrh->sapi;
int i, rc;
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' from RR in state %s\n",
- ms->name, get_rr_name(msg_type),
- gsm48_mm_state_names[mm->state]);
+ LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' from RR in state %s "
+ "(sapi %d)\n", ms->name, get_rr_name(msg_type),
+ gsm48_mm_state_names[mm->state], sapi);
+
+ if (sapi)
+ return gsm48_rcv_rr_sapi3(ms, msg, msg_type, sapi);
/* find function for current state and message */
for (i = 0; i < RRDATASLLEN; i++)
@@ -3820,7 +3916,7 @@ static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg)
}
rc = rrdatastatelist[i].rout(ms, msg);
-
+
if (rrdatastatelist[i].rout != gsm48_mm_data_ind)
msgb_free(msg);
@@ -3870,6 +3966,8 @@ static struct mmdatastate {
static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_mmlayer *mm = &ms->mmlayer;
+ struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
+ int sapi = rrh->sapi;
struct gsm48_hdr *gh = msgb_l3(msg);
uint8_t pdisc = gh->proto_discr & 0x0f;
uint8_t msg_type = gh->msg_type & 0xbf;
@@ -3880,12 +3978,15 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
int i, rc;
/* 9.2.19 */
- if (msg_type == GSM48_MT_MM_NULL)
+ if (msg_type == GSM48_MT_MM_NULL) {
+ msgb_free(msg);
return 0;
+ }
if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
LOGP(DMM, LOGL_NOTICE, "DATA IND ignored during IMSI "
"detach.\n");
+ msgb_free(msg);
return 0;
}
/* pull the RR header */
@@ -3897,7 +3998,6 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
rr_prim = GSM48_MMCC_DATA_IND;
rr_est = GSM48_MMCC_EST_IND;
break;
-#if 0
case GSM48_PDISC_NC_SS:
rr_prim = GSM48_MMSS_DATA_IND;
rr_est = GSM48_MMSS_EST_IND;
@@ -3906,7 +4006,6 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
rr_prim = GSM48_MMSMS_DATA_IND;
rr_est = GSM48_MMSMS_EST_IND;
break;
-#endif
}
if (rr_prim != -1) {
uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
@@ -3918,18 +4017,22 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
/* create MM connection instance */
if (!conn) {
- conn = mm_conn_new(mm, pdisc, transaction_id,
+ conn = mm_conn_new(mm, pdisc, transaction_id, sapi,
mm_conn_new_ref++);
rr_prim = rr_est;
}
- if (!conn)
+ if (!conn) {
+ msgb_free(msg);
return -ENOMEM;
+ }
/* push new header */
msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
mmh = (struct gsm48_mmxx_hdr *)msg->data;
mmh->msg_type = rr_prim;
mmh->ref = conn->ref;
+ mmh->transaction_id = conn->transaction_id;
+ mmh->sapi = conn->sapi;
/* go MM CONN ACTIVE state */
if (mm->state == GSM48_MM_ST_WAIT_NETWORK_CMD
@@ -3950,24 +4053,35 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
skip_ind = (gh->proto_discr & 0xf0) >> 4;
/* ignore if skip indicator is not B'0000' */
- if (skip_ind)
+ if (skip_ind) {
+ msgb_free(msg);
return 0;
+ }
break; /* follow the selection proceedure below */
case GSM48_PDISC_CC:
- return gsm48_rcv_cc(ms, msg);
+ rc = gsm48_rcv_cc(ms, msg);
+ msgb_free(msg);
+ return rc;
-#if 0
case GSM48_PDISC_NC_SS:
- return gsm48_rcv_ss(ms, msg);
+ rc = gsm480_rcv_ss(ms, msg);
+ msgb_free(msg);
+ return rc;
case GSM48_PDISC_SMS:
- return gsm48_rcv_sms(ms, msg);
-#endif
+ rc = gsm411_rcv_sms(ms, msg);
+ msgb_free(msg);
+ return rc;
+ case 0x0f: /* test TS 04.14 */
+ LOGP(DMM, LOGL_NOTICE, "Test protocol 0x%02x according to "
+ "TS 04.14 is not supported.\n", pdisc);
+ goto status;
default:
LOGP(DMM, LOGL_NOTICE, "Protocol type 0x%02x unsupported.\n",
pdisc);
+status:
msgb_free(msg);
return gsm48_mm_tx_mm_status(ms,
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
@@ -4136,8 +4250,8 @@ static struct eventstate {
{ALL_STATES, ALL_STATES,
GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_delay},
- {GSM48_MM_ST_IMSI_DETACH_INIT, ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_end},
+ {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), ALL_STATES,
+ GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_abort},
/* location update in other cases */
{SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
@@ -4166,7 +4280,8 @@ static struct eventstate {
GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
/* T3230 timed out */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
+ {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
+ SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
GSM48_MM_EVENT_TIMEOUT_T3230, gsm48_mm_timeout_mm_con},
/* SIM reports SRES */
diff --git a/Src/osmolib/src/host/layer23/src/mobile/gsm48_rr.c b/Src/osmolib/src/host/layer23/src/mobile/gsm48_rr.c
index c1e386a..b6083af 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/gsm48_rr.c
@@ -145,7 +145,7 @@ static int gsm48_decode_ba_range(const uint8_t *ba, uint8_t ba_len,
*/
uint16_t lower, higher;
int i, n, required_octets;
-
+
/* find out how much ba ranges will be decoded */
n = *ba++;
ba_len --;
@@ -351,7 +351,7 @@ const char *gsm48_rr_state_names[] = {
static void new_rr_state(struct gsm48_rrlayer *rr, int state)
{
- if (state < 0 || state >=
+ if (state < 0 || state >=
(sizeof(gsm48_rr_state_names) / sizeof(char *)))
return;
@@ -422,6 +422,26 @@ static void new_rr_state(struct gsm48_rrlayer *rr, int state)
}
}
+const char *gsm48_sapi3_state_names[] = {
+ "idle",
+ "wait establishment",
+ "established",
+ "wait release",
+};
+
+static void new_sapi3_state(struct gsm48_rrlayer *rr, int state)
+{
+ if (state < 0 || state >=
+ (sizeof(gsm48_sapi3_state_names) / sizeof(char *)))
+ return;
+
+ LOGP(DRR, LOGL_INFO, "new SAPI 3 link state %s -> %s\n",
+ gsm48_sapi3_state_names[rr->sapi3_state],
+ gsm48_sapi3_state_names[state]);
+
+ rr->sapi3_state = state;
+}
+
/*
* messages
*/
@@ -504,7 +524,7 @@ int gsm48_rr_upmsg(struct osmocom_ms *ms, struct msgb *msg)
/* push rsl header and send (RSL-SAP) */
static int gsm48_send_rsl(struct osmocom_ms *ms, uint8_t msg_type,
- struct msgb *msg)
+ struct msgb *msg, uint8_t link_id)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
@@ -512,20 +532,19 @@ static int gsm48_send_rsl(struct osmocom_ms *ms, uint8_t msg_type,
LOGP(DRR, LOGL_ERROR, "FIX l3h\n");
return -EINVAL;
}
- rsl_rll_push_l3(msg, msg_type, rr->cd_now.chan_nr,
- rr->cd_now.link_id, 1);
+ rsl_rll_push_l3(msg, msg_type, rr->cd_now.chan_nr, link_id, 1);
return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
}
-/* push rsl header + release mode and send (RSL-SAP) */
-static int gsm48_send_rsl_rel(struct osmocom_ms *ms, uint8_t msg_type,
- struct msgb *msg)
+/* push rsl header without L3 info and send (RSL-SAP) */
+static int gsm48_send_rsl_nol3(struct osmocom_ms *ms, uint8_t msg_type,
+ struct msgb *msg, uint8_t link_id)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
rsl_rll_push_hdr(msg, msg_type, rr->cd_now.chan_nr,
- rr->cd_now.link_id, 1);
+ link_id, 1);
return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
}
@@ -547,13 +566,13 @@ int gsm48_rsl_dequeue(struct osmocom_ms *ms)
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct msgb *msg;
int work = 0;
-
+
while ((msg = msgb_dequeue(&rr->rsl_upqueue))) {
/* msg is freed there */
gsm48_rcv_rsl(ms, msg);
work = 1; /* work done */
}
-
+
return work;
}
@@ -571,6 +590,43 @@ int gsm48_rr_stop_monitor(struct osmocom_ms *ms)
return 0;
}
+/* release L3 link in both directions in case of main link release */
+static int gsm48_release_sapi3_link(struct osmocom_ms *ms)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+ struct gsm48_rr_hdr *nrrh;
+ struct msgb *nmsg;
+ uint8_t *mode;
+
+ if (rr->sapi3_state == GSM48_RR_SAPI3ST_IDLE)
+ return 0;
+
+ LOGP(DRR, LOGL_INFO, "Main signallin link is down, so release SAPI 3 "
+ "link locally.\n");
+
+ new_sapi3_state(rr, GSM48_RR_SAPI3ST_IDLE);
+
+ /* disconnect the SAPI 3 signalling link */
+ nmsg = gsm48_l3_msgb_alloc();
+ if (!nmsg)
+ return -ENOMEM;
+ mode = msgb_put(nmsg, 2);
+ mode[0] = RSL_IE_RELEASE_MODE;
+ mode[1] = 1; /* local release */
+ gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, rr->sapi3_link_id);
+
+ /* send inication to upper layer */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *)nmsg->data;
+ nrrh->cause = RR_REL_CAUSE_NORMAL;
+ nrrh->sapi = rr->sapi3_link_id & 7;
+ gsm48_rr_upmsg(ms, nmsg);
+
+ return 0;
+}
+
/*
* timers handling
*/
@@ -598,7 +654,7 @@ static void timeout_rr_meas(void *arg)
snr = (meas->snr + meas->frames / 2) / meas->frames;
sprintf(text, "MON: f=%d lev=%s snr=%2d ber=%3d "
"LAI=%s %s %04x ID=%04x", cs->sel_arfcn,
- gsm_print_rxlev(rxlev), berr, snr,
+ gsm_print_rxlev(rxlev), berr, snr,
gsm_print_mcc(cs->sel_mcc),
gsm_print_mnc(cs->sel_mnc), cs->sel_lac, cs->sel_id);
if (rr->state == GSM48_RR_ST_DEDICATED) {
@@ -646,7 +702,11 @@ static void timeout_rr_t_starting(void *arg)
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return;
- gsm48_send_rsl(rr->ms, RSL_MT_SUSP_REQ, nmsg);
+ gsm48_send_rsl(rr->ms, RSL_MT_SUSP_REQ, nmsg, 0);
+
+ /* release SAPI 3 link, if exits
+ * FIXME: suspend and resume afterward */
+ gsm48_release_sapi3_link(rr->ms);
}
/* special timer to ensure that UA is sent before disconnecting channel */
@@ -679,7 +739,10 @@ static void timeout_rr_t3110(void *arg)
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 1; /* local release */
- gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
+ gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
+
+ /* release SAPI 3 link, if exits */
+ gsm48_release_sapi3_link(ms);
return;
}
@@ -857,7 +920,7 @@ static int gsm48_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause)
/* rr cause */
st->rr_cause = cause;
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
}
/*
@@ -892,7 +955,7 @@ static int gsm48_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr)
memcpy(tlv, buf, 2 + buf[1]);
}
- gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
/* send RR_SYNC_IND(ciphering) */
nmsg = gsm48_rr_msgb_alloc(GSM48_RR_SYNC_IND);
@@ -1224,7 +1287,7 @@ static int gsm48_rr_tx_cm_change(struct osmocom_ms *ms)
memcpy(tlv, cm3, 2 + cm3[1]);
}
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
}
/* receiving classmark enquiry */
@@ -1239,7 +1302,8 @@ static int gsm48_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg)
*/
/* start random access */
-static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
+static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging,
+ int paging_mi_type)
{
struct gsm_settings *set = &ms->settings;
struct gsm48_rrlayer *rr = &ms->rrlayer;
@@ -1450,6 +1514,9 @@ rel_ind:
* after location updating */
rr->est_cause = cause;
+ /* store paging mobile identity type, if we respond to paging */
+ rr->paging_mi_type = paging_mi_type;
+
/* if channel is already active somehow */
if (cs->ccch_state == GSM322_CCCH_ST_DATA)
return gsm48_rr_tx_rand_acc(ms, NULL);
@@ -2037,7 +2104,7 @@ static int gsm48_rr_chan2cause[4] = {
};
/* given LV of mobile identity is checked agains ms */
-static int gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
+static uint8_t gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
{
struct gsm322_cellsel *cs = &ms->cellsel;
char imsi[16];
@@ -2059,7 +2126,7 @@ static int gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n",
ntohl(tmsi));
- return 1;
+ return mi_type;
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(tmsi));
@@ -2069,7 +2136,7 @@ static int gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
if (!strcmp(imsi, ms->subscr.imsi)) {
LOGP(DPAG, LOGL_INFO, " IMSI %s matches\n", imsi);
- return 1;
+ return mi_type;
} else
LOGP(DPAG, LOGL_INFO, " IMSI %s (not for us)\n", imsi);
break;
@@ -2089,7 +2156,7 @@ static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_paging1 *pa = msgb_l3(msg);
int payload_len = msgb_l3len(msg) - sizeof(*pa);
int chan_1, chan_2;
- uint8_t *mi;
+ uint8_t *mi, mi_type;
/* empty paging request */
if (payload_len >= 2 && (pa->data[1] & GSM_MI_TYPE_MASK) == 0)
@@ -2121,8 +2188,9 @@ static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
mi = pa->data;
if (payload_len < mi[0] + 1)
goto short_read;
- if (gsm_match_mi(ms, mi) > 0)
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
+ if ((mi_type = gsm_match_mi(ms, mi)) > 0)
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1,
+ mi_type);
/* second MI */
payload_len -= mi[0] + 1;
mi = pa->data + mi[0] + 1;
@@ -2132,8 +2200,9 @@ static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
return 0;
if (payload_len < mi[1] + 2)
goto short_read;
- if (gsm_match_mi(ms, mi + 1) > 0)
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
+ if ((mi_type = gsm_match_mi(ms, mi + 1)) > 0)
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1,
+ mi_type);
return 0;
}
@@ -2145,7 +2214,7 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
struct gsm322_cellsel *cs = &ms->cellsel;
struct gsm48_paging2 *pa = msgb_l3(msg);
int payload_len = msgb_l3len(msg) - sizeof(*pa);
- uint8_t *mi;
+ uint8_t *mi, mi_type;
int chan_1, chan_2, chan_3;
/* 3.3.1.1.2: ignore paging while not camping on a cell */
@@ -2176,7 +2245,8 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
&& ms->subscr.mnc == cs->sel_mnc
&& ms->subscr.lac == cs->sel_lac) {
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1,
+ GSM_MI_TYPE_TMSI);
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(pa->tmsi1));
@@ -2186,7 +2256,8 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
&& ms->subscr.mnc == cs->sel_mnc
&& ms->subscr.lac == cs->sel_lac) {
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1,
+ GSM_MI_TYPE_TMSI);
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(pa->tmsi2));
@@ -2199,8 +2270,9 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
if (payload_len < mi[1] + 2 + 1) /* must include "channel needed" */
goto short_read;
chan_3 = mi[mi[1] + 2] & 0x03; /* channel needed */
- if (gsm_match_mi(ms, mi + 1) > 0)
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1);
+ if ((mi_type = gsm_match_mi(ms, mi + 1)) > 0)
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1,
+ mi_type);
return 0;
}
@@ -2243,7 +2315,8 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
&& ms->subscr.mnc == cs->sel_mnc
&& ms->subscr.lac == cs->sel_lac) {
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1,
+ GSM_MI_TYPE_TMSI);
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(pa->tmsi1));
@@ -2253,7 +2326,8 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
&& ms->subscr.mnc == cs->sel_mnc
&& ms->subscr.lac == cs->sel_lac) {
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1,
+ GSM_MI_TYPE_TMSI);
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(pa->tmsi2));
@@ -2263,7 +2337,8 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
&& ms->subscr.mnc == cs->sel_mnc
&& ms->subscr.lac == cs->sel_lac) {
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi3));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1);
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1,
+ GSM_MI_TYPE_TMSI);
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(pa->tmsi3));
@@ -2273,7 +2348,8 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
&& ms->subscr.mnc == cs->sel_mnc
&& ms->subscr.lac == cs->sel_lac) {
LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi4));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_4], 1);
+ return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_4], 1,
+ GSM_MI_TYPE_TMSI);
} else
LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
ntohl(pa->tmsi4));
@@ -2415,7 +2491,7 @@ static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
/* timing advance */
rr->cd_now.ind_ta = ia->timing_advance;
/* mobile allocation */
- memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
+ memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
ia->mob_alloc_len + 1);
rr->wait_assign = 2;
/* reset scheduler */
@@ -2850,7 +2926,10 @@ int gsm48_rr_los(struct osmocom_ms *ms)
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 1; /* local release */
/* start release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
+ gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
+ /* release SAPI 3 link, if exits */
+ gsm48_release_sapi3_link(ms);
+ return 0;
case GSM48_RR_ST_REL_PEND:
LOGP(DRR, LOGL_INFO, "LOS during RR release procedure, release "
"locally\n");
@@ -2991,7 +3070,7 @@ static int gsm48_rr_render_ma(struct osmocom_ms *ms, struct gsm48_rr_cd *cd,
/* decode mobile allocation */
if (cd->mob_alloc_lv[0]) {
struct gsm_sysinfo_freq *freq = s->freq;
-
+
LOGP(DRR, LOGL_INFO, "decoding mobile allocation\n");
if (cd->cell_desc_lv[0]) {
@@ -3172,7 +3251,7 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
gh->msg_type = GSM48_MT_RR_PAG_RESP;
pr = (struct gsm48_pag_rsp *) msgb_put(nmsg, sizeof(*pr));
/* key sequence */
- pr->key_seq = subscr->key_seq;
+ pr->key_seq = gsm_subscr_get_key_seq(ms, subscr);
/* classmark 2 */
pr->cm2_len = sizeof(pr->cm2);
gsm48_rr_enc_cm2(ms, &pr->cm2, rr->cd_now.arfcn);
@@ -3180,7 +3259,8 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
if (ms->subscr.tmsi != 0xffffffff
&& ms->subscr.mcc == cs->sel_mcc
&& ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
+ && ms->subscr.lac == cs->sel_lac
+ && rr->paging_mi_type == GSM_MI_TYPE_TMSI) {
gsm48_generate_mid_from_tmsi(mi, subscr->tmsi);
LOGP(DRR, LOGL_INFO, "sending paging response with "
"TMSI\n");
@@ -3216,7 +3296,7 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
#endif
/* start establishmnet */
- return gsm48_send_rsl(ms, RSL_MT_EST_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_EST_REQ, nmsg, 0);
}
/* the link is established */
@@ -3237,7 +3317,7 @@ static int gsm48_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg)
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 0; /* normal release */
/* start release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
+ return gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
}
/* 3.3.1.1.4 */
@@ -3286,6 +3366,9 @@ static int gsm48_rr_rel_ind(struct osmocom_ms *ms, struct msgb *msg)
/* pending release */
new_rr_state(rr, GSM48_RR_ST_REL_PEND);
+ /* also release SAPI 3 link, if exists */
+ gsm48_release_sapi3_link(ms);
+
return 0;
}
@@ -3308,7 +3391,7 @@ static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
}
tlv_parse(&tp, &gsm48_rr_att_tlvdef, cr->data, payload_len, 0, 0);
- LOGP(DRR, LOGL_INFO, "channel release request with cause 0x%02x)\n",
+ LOGP(DRR, LOGL_INFO, "channel release request with cause 0x%02x\n",
cr->rr_cause);
/* BA range */
@@ -3334,7 +3417,11 @@ static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 0; /* normal release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
+ gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
+
+ /* release SAPI 3 link, if exits */
+ gsm48_release_sapi3_link(ms);
+ return 0;
}
/*
@@ -3411,7 +3498,7 @@ static int gsm48_rr_rx_frq_redef(struct osmocom_ms *ms, struct msgb *msg)
}
/* mobile allocation */
- memcpy(rr->cd_now.mob_alloc_lv, &fr->mob_alloc_len,
+ memcpy(rr->cd_now.mob_alloc_lv, &fr->mob_alloc_len,
fr->mob_alloc_len + 1);
/* starting time */
@@ -3469,7 +3556,7 @@ static int gsm48_rr_tx_chan_modify_ack(struct osmocom_ms *ms,
/* mode */
cm->mode = mode;
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg, 0);
}
/* 9.1.5 CHANNEL MODE MODIFY is received */
@@ -3547,7 +3634,7 @@ static int gsm48_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
/* RR_CAUSE */
ac->rr_cause = cause;
- return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg, 0);
}
/* 9.1.4 sending ASSIGNMENT FAILURE */
@@ -3572,7 +3659,7 @@ static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause,
/* RR_CAUSE */
af->rr_cause = cause;
- return gsm48_send_rsl(ms, rsl_prim, nmsg);
+ return gsm48_send_rsl(ms, rsl_prim, nmsg, 0);
}
/* 9.1.2 ASSIGNMENT COMMAND is received */
@@ -3663,8 +3750,8 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
cda->start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
#else
- if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
- gsm48_decode_start_time(cda, (struct gsm48_start_time *)
+ if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
+ gsm48_decode_start_time(cda, (struct gsm48_start_time *)
TLVP_VAL(&tp, GSM48_IE_START_TIME));
/* 9.1.2.5 "... before time IE is not present..." */
if (!before_time) {
@@ -3882,7 +3969,11 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
- gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg);
+ gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg, 0);
+
+ /* release SAPI 3 link, if exits
+ * FIXME: suspend and resume afterward */
+ gsm48_release_sapi3_link(ms);
return 0;
}
@@ -3910,7 +4001,7 @@ static int gsm48_rr_tx_hando_cpl(struct osmocom_ms *ms, uint8_t cause)
// FIXME: mobile observed time
- return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg, 0);
}
/* 9.1.4 sending HANDOVER FAILURE */
@@ -3935,7 +4026,7 @@ static int gsm48_rr_tx_hando_fail(struct osmocom_ms *ms, uint8_t cause,
/* RR_CAUSE */
hf->rr_cause = cause;
- return gsm48_send_rsl(ms, rsl_prim, nmsg);
+ return gsm48_send_rsl(ms, rsl_prim, nmsg, 0);
}
/* receiving HANDOVER COMMAND message (9.1.15) */
@@ -3984,8 +4075,8 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
tlv_parse(&tp, &gsm48_rr_att_tlvdef, ho->data, payload_len, 0, 0);
/* sync ind */
- if (TLVP_PRESENT(&tp, GSM48_IE_SYNC_IND)) {
- gsm48_decode_sync_ind(rr, (struct gsm48_sync_ind *)
+ if (TLVP_PRESENT(&tp, GSM48_IE_SYNC_IND)) {
+ gsm48_decode_sync_ind(rr, (struct gsm48_sync_ind *)
TLVP_VAL(&tp, GSM48_IE_SYNC_IND));
LOGP(DRR, LOGL_INFO, " (sync_ind=%d rot=%d nci=%d)\n",
rr->hando_sync_ind, rr->hando_rot, rr->hando_nci);
@@ -4043,8 +4134,8 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
cda->start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
#else
- if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
- gsm48_decode_start_time(cda, (struct gsm48_start_time *)
+ if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
+ gsm48_decode_start_time(cda, (struct gsm48_start_time *)
TLVP_VAL(&tp, GSM48_IE_START_TIME));
/* 9.1.2.5 "... before time IE is not present..." */
if (!before_time) {
@@ -4268,7 +4359,11 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
- gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg);
+ gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg, 0);
+
+ /* release SAPI 3 link, if exits
+ * FIXME: suspend and resume afterward */
+ gsm48_release_sapi3_link(ms);
return 0;
}
@@ -4280,8 +4375,16 @@ static int gsm48_rr_dequeue_down(struct osmocom_ms *ms)
struct msgb *msg;
while((msg = msgb_dequeue(&rr->downqueue))) {
+ struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
+ uint8_t sapi = rrh->sapi;
+
LOGP(DRR, LOGL_INFO, "Sending queued message.\n");
- gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg);
+ if (sapi && rr->sapi3_state != GSM48_RR_SAPI3ST_ESTAB) {
+ LOGP(DRR, LOGL_INFO, "Dropping SAPI 3 msg, no link!\n");
+ msgb_free(msg);
+ return 0;
+ }
+ gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg, 0);
}
return 0;
@@ -4370,7 +4473,7 @@ static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
}
/*
- * radio ressource requests
+ * radio ressource requests
*/
/* establish request for dedicated mode */
@@ -4475,19 +4578,21 @@ static int gsm48_rr_est_req(struct osmocom_ms *ms, struct msgb *msg)
msgb_l3(msg), msgb_l3len(msg));
/* request channel */
- return gsm48_rr_chan_req(ms, rrh->cause, 0);
+ return gsm48_rr_chan_req(ms, rrh->cause, 0, 0);
}
/* 3.4.2 transfer data in dedicated mode */
static int gsm48_rr_data_req(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
+ struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
+ uint8_t sapi = rrh->sapi;
if (rr->state != GSM48_RR_ST_DEDICATED) {
msgb_free(msg);
return -EINVAL;
}
-
+
/* pull RR header */
msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
@@ -4502,8 +4607,15 @@ static int gsm48_rr_data_req(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
+ if (sapi && rr->sapi3_state != GSM48_RR_SAPI3ST_ESTAB) {
+ LOGP(DRR, LOGL_INFO, "Dropping SAPI 3 msg, no link!\n");
+ msgb_free(msg);
+ return 0;
+ }
+
/* forward message */
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg);
+ return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg,
+ sapi ? rr->sapi3_link_id : 0);
}
/*
@@ -4684,7 +4796,7 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
struct tlv_parsed tv;
uint8_t ch_type, ch_subch, ch_ts;
-
+
DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
rllh->chan_nr, rllh->link_id);
@@ -4765,7 +4877,11 @@ static int gsm48_rr_abort_req(struct osmocom_ms *ms, struct msgb *msg)
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 0; /* normal release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
+ gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, 0);
+
+ /* release SAPI 3 link, if exits */
+ gsm48_release_sapi3_link(ms);
+ return 0;
}
LOGP(DRR, LOGL_INFO, "Abort in connection pending state, return to "
@@ -4853,6 +4969,7 @@ static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_rr_hdr *nrrh;
uint8_t *mode;
uint8_t cause = rllh->data[2];
+ uint8_t link_id = rllh->link_id;
switch (cause) {
case RLL_CAUSE_SEQ_ERR:
@@ -4865,14 +4982,14 @@ static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_NOTICE, "MDL-Error (cause %d) aborting\n", cause);
- /* disconnect the main signalling link */
+ /* disconnect the (main) signalling link */
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 1; /* local release */
- gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
+ gsm48_send_rsl_nol3(ms, RSL_MT_REL_REQ, nmsg, link_id);
/* in case of modify/hando: wait for confirm */
if (rr->modify_state)
@@ -4884,13 +5001,191 @@ static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
return -ENOMEM;
nrrh = (struct gsm48_rr_hdr *)nmsg->data;
nrrh->cause = RR_REL_CAUSE_LINK_FAILURE;
+ nrrh->sapi = link_id & 7;
gsm48_rr_upmsg(ms, nmsg);
- /* return idle */
- new_rr_state(rr, GSM48_RR_ST_IDLE);
+ /* only for main signalling link */
+ if ((link_id & 7) == 0) {
+ /* return idle */
+ new_rr_state(rr, GSM48_RR_ST_IDLE);
+ /* release SAPI 3 link, if exits */
+ gsm48_release_sapi3_link(ms);
+ } else {
+ new_sapi3_state(rr, GSM48_RR_SAPI3ST_IDLE);
+ LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 failed\n");
+ }
return 0;
}
+static int gsm48_rr_estab_ind_sapi3(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ uint8_t link_id = rllh->link_id;
+ struct msgb *nmsg;
+ struct gsm48_rr_hdr *nrrh;
+
+ if (rr->state != GSM48_RR_ST_DEDICATED) {
+ /* disconnect sapi 3 link */
+ gsm48_release_sapi3_link(ms);
+ return -EINVAL;
+ }
+
+ new_sapi3_state(rr, GSM48_RR_SAPI3ST_ESTAB);
+ rr->sapi3_link_id = link_id; /* set link ID */
+
+ LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 is established\n");
+
+ /* send inication to upper layer */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_EST_IND);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *)nmsg->data;
+ nrrh->sapi = link_id & 7;
+
+ return gsm48_rr_upmsg(ms, nmsg);
+}
+
+static int gsm48_rr_estab_cnf_sapi3(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ uint8_t link_id = rllh->link_id;
+ struct msgb *nmsg;
+ struct gsm48_rr_hdr *nrrh;
+
+ if (rr->state != GSM48_RR_ST_DEDICATED) {
+ gsm48_release_sapi3_link(ms);
+ return -EINVAL;
+ }
+
+ new_sapi3_state(rr, GSM48_RR_SAPI3ST_ESTAB);
+ rr->sapi3_link_id = link_id; /* set link ID, just to be sure */
+
+ LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 is established\n");
+
+ /* send inication to upper layer */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_EST_CNF);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *)nmsg->data;
+ nrrh->sapi = link_id & 7;
+
+ return gsm48_rr_upmsg(ms, nmsg);
+}
+
+/* 3.4.2 data from layer 2 to RR and upper layer (sapi 3)*/
+static int gsm48_rr_data_ind_sapi3(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ uint8_t sapi = rllh->link_id & 7;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ struct gsm48_rr_hdr *rrh;
+ uint8_t pdisc = gh->proto_discr & 0x0f;
+
+ if (pdisc == GSM48_PDISC_RR) {
+ msgb_free(msg);
+ return -EINVAL;
+ }
+
+ /* pull off RSL header up to L3 message */
+ msgb_pull(msg, (long)msgb_l3(msg) - (long)msg->data);
+
+ /* push RR header */
+ msgb_push(msg, sizeof(struct gsm48_rr_hdr));
+ rrh = (struct gsm48_rr_hdr *)msg->data;
+ rrh->msg_type = GSM48_RR_DATA_IND;
+ rrh->sapi = sapi;
+
+ return gsm48_rr_upmsg(ms, msg);
+}
+
+static int gsm48_rr_rel_ind_sapi3(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ uint8_t link_id = rllh->link_id;
+ struct msgb *nmsg;
+ struct gsm48_rr_hdr *nrrh;
+
+ new_sapi3_state(rr, GSM48_RR_SAPI3ST_IDLE);
+
+ LOGP(DSUM, LOGL_INFO, "Radio link SAPI3 is released\n");
+
+ /* send inication to upper layer */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *)nmsg->data;
+ nrrh->cause = RR_REL_CAUSE_NORMAL;
+ nrrh->sapi = link_id & 7;
+
+ return gsm48_rr_upmsg(ms, nmsg);
+}
+
+/* request SAPI 3 establishment */
+static int gsm48_rr_est_req_sapi3(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+ uint8_t ch_type, ch_subch, ch_ts;
+ struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
+ uint8_t sapi = rrh->sapi;
+ struct msgb *nmsg;
+
+ if (rr->state != GSM48_RR_ST_DEDICATED) {
+ struct gsm48_rr_hdr *nrrh;
+
+ /* send inication to upper layer */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *)nmsg->data;
+ nrrh->cause = RR_REL_CAUSE_NORMAL;
+ nrrh->sapi = sapi;
+ return gsm48_rr_upmsg(ms, nmsg);
+ }
+
+ rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
+ if (ch_type != RSL_CHAN_Bm_ACCHs
+ && ch_type != RSL_CHAN_Lm_ACCHs) {
+ LOGP(DRR, LOGL_INFO, "Requesting DCCH link, because no TCH "
+ "(sapi %d)\n", sapi);
+ rr->sapi3_link_id = 0x00 | sapi; /* SAPI 3, DCCH */
+ } else {
+ LOGP(DRR, LOGL_INFO, "Requesting ACCH link, because TCH "
+ "(sapi %d)\n", sapi);
+ rr->sapi3_link_id = 0x40 | sapi; /* SAPI 3, ACCH */
+ }
+
+ /* already established */
+ new_sapi3_state(rr, GSM48_RR_SAPI3ST_WAIT_EST);
+
+ /* send message */
+ nmsg = gsm48_l3_msgb_alloc();
+ if (!nmsg)
+ return -ENOMEM;
+ return gsm48_send_rsl_nol3(ms, RSL_MT_EST_REQ, nmsg, rr->sapi3_link_id);
+}
+
+static int gsm48_rr_est_req_estab_sapi3(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
+ uint8_t sapi = rrh->sapi;
+ struct msgb *nmsg;
+ struct gsm48_rr_hdr *nrrh;
+
+ LOGP(DRR, LOGL_INFO, "Radio link SAPI3 already established\n");
+
+ /* send inication to upper layer */
+ nmsg = gsm48_rr_msgb_alloc(GSM48_RR_EST_CNF);
+ if (!nmsg)
+ return -ENOMEM;
+ nrrh = (struct gsm48_rr_hdr *)nmsg->data;
+ nrrh->sapi = sapi;
+
+ return gsm48_rr_upmsg(ms, nmsg);
+}
+
/*
* state machines
*/
@@ -4901,6 +5196,8 @@ static struct dldatastate {
int type;
int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
} dldatastatelist[] = {
+ /* SAPI 0 on DCCH */
+
/* data transfer */
{SBIT(GSM48_RR_ST_IDLE) |
SBIT(GSM48_RR_ST_CONN_PEND) |
@@ -4950,35 +5247,79 @@ static struct dldatastate {
#define DLDATASLLEN \
(sizeof(dldatastatelist) / sizeof(struct dldatastate))
+static struct dldatastate dldatastatelists3[] = {
+ /* SAPI 3 on DCCH */
+
+ /* establish */
+ {SBIT(GSM48_RR_SAPI3ST_IDLE),
+ RSL_MT_EST_IND, gsm48_rr_estab_ind_sapi3},
+
+ /* establish */
+ {SBIT(GSM48_RR_SAPI3ST_IDLE) | SBIT(GSM48_RR_SAPI3ST_WAIT_EST),
+ RSL_MT_EST_CONF, gsm48_rr_estab_cnf_sapi3},
+
+ /* data transfer */
+ {SBIT(GSM48_RR_SAPI3ST_ESTAB),
+ RSL_MT_DATA_IND, gsm48_rr_data_ind_sapi3},
+
+ /* release */
+ {SBIT(GSM48_RR_SAPI3ST_WAIT_EST) | SBIT(GSM48_RR_SAPI3ST_ESTAB),
+ RSL_MT_REL_IND, gsm48_rr_rel_ind_sapi3},
+
+ {ALL_STATES,
+ RSL_MT_ERROR_IND, gsm48_rr_mdl_error_ind},
+};
+
+#define DLDATASLLENS3 \
+ (sizeof(dldatastatelists3) / sizeof(struct dldatastate))
+
static int gsm48_rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
int msg_type = rllh->c.msg_type;
+ int link_id = rllh->link_id;
int i;
int rc;
- if (msg_type != RSL_MT_UNIT_DATA_IND) {
- LOGP(DRSL, LOGL_INFO, "(ms %s) Received '%s' from L2 in state "
- "%s\n", ms->name, rsl_msg_name(msg_type),
- gsm48_rr_state_names[rr->state]);
- }
+ LOGP(DRSL, LOGL_INFO, "(ms %s) Received '%s' from L2 in state "
+ "%s (link_id 0x%x)\n", ms->name, rsl_msg_name(msg_type),
+ gsm48_rr_state_names[rr->state], link_id);
/* find function for current state and message */
- for (i = 0; i < DLDATASLLEN; i++)
- if ((msg_type == dldatastatelist[i].type)
- && ((1 << rr->state) & dldatastatelist[i].states))
- break;
- if (i == DLDATASLLEN) {
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
- msgb_free(msg);
- return 0;
- }
+ if (!(link_id & 7)) {
+ /* SAPI 0 */
+ for (i = 0; i < DLDATASLLEN; i++)
+ if ((msg_type == dldatastatelist[i].type)
+ && ((1 << rr->state) & dldatastatelist[i].states))
+ break;
+ if (i == DLDATASLLEN) {
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message '%s' "
+ "unhandled\n", rsl_msg_name(msg_type));
+ msgb_free(msg);
+ return 0;
+ }
+
+ rc = dldatastatelist[i].rout(ms, msg);
+ } else {
+ /* SAPI 3 */
+ for (i = 0; i < DLDATASLLENS3; i++)
+ if ((msg_type == dldatastatelists3[i].type)
+ && ((1 << rr->sapi3_state) &
+ dldatastatelists3[i].states))
+ break;
+ if (i == DLDATASLLENS3) {
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message '%s' "
+ "unhandled\n", rsl_msg_name(msg_type));
+ msgb_free(msg);
+ return 0;
+ }
- rc = dldatastatelist[i].rout(ms, msg);
+ rc = dldatastatelists3[i].rout(ms, msg);
+ }
/* free msgb unless it is forwarded */
- if (dldatastatelist[i].rout != gsm48_rr_data_ind)
+ if (msg_type != RSL_MT_DATA_IND)
msgb_free(msg);
return rc;
@@ -5033,12 +5374,14 @@ static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg)
return rc;
}
-/* state trasitions for RR-SAP messages from up */
+/* state trasitions for RR-SAP messages from up (main link) */
static struct rrdownstate {
uint32_t states;
int type;
int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
} rrdownstatelist[] = {
+ /* SAPI 0 */
+
/* NOTE: If not IDLE, it is rejected there. */
{ALL_STATES, /* 3.3.1.1 */
GSM48_RR_EST_REQ, gsm48_rr_est_req},
@@ -5054,33 +5397,69 @@ static struct rrdownstate {
#define RRDOWNSLLEN \
(sizeof(rrdownstatelist) / sizeof(struct rrdownstate))
+/* state trasitions for RR-SAP messages from up with (SAPI 3) */
+static struct rrdownstate rrdownstatelists3[] = {
+ /* SAPI 3 */
+
+ {SBIT(GSM48_RR_SAPI3ST_IDLE),
+ GSM48_RR_EST_REQ, gsm48_rr_est_req_sapi3},
+
+ {SBIT(GSM48_RR_SAPI3ST_ESTAB),
+ GSM48_RR_EST_REQ, gsm48_rr_est_req_estab_sapi3},
+
+ {SBIT(GSM48_RR_SAPI3ST_ESTAB),
+ GSM48_RR_DATA_REQ, gsm48_rr_data_req}, /* handles SAPI 3 too */
+};
+
+#define RRDOWNSLLENS3 \
+ (sizeof(rrdownstatelists3) / sizeof(struct rrdownstate))
+
int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
int msg_type = rrh->msg_type;
+ int sapi = rrh->sapi;
int i;
int rc;
- LOGP(DRR, LOGL_INFO, "(ms %s) Message '%s' received in state %s\n",
- ms->name, get_rr_name(msg_type),
- gsm48_rr_state_names[rr->state]);
+ LOGP(DRR, LOGL_INFO, "(ms %s) Message '%s' received in state %s "
+ "(sapi %d)\n", ms->name, get_rr_name(msg_type),
+ gsm48_rr_state_names[rr->state], sapi);
- /* find function for current state and message */
- for (i = 0; i < RRDOWNSLLEN; i++)
- if ((msg_type == rrdownstatelist[i].type)
- && ((1 << rr->state) & rrdownstatelist[i].states))
- break;
- if (i == RRDOWNSLLEN) {
- LOGP(DRR, LOGL_NOTICE, "Message unhandled at this state.\n");
- msgb_free(msg);
- return 0;
- }
+ if (!sapi) {
+ /* SAPI 0: find function for current state and message */
+ for (i = 0; i < RRDOWNSLLEN; i++)
+ if ((msg_type == rrdownstatelist[i].type)
+ && ((1 << rr->state) & rrdownstatelist[i].states))
+ break;
+ if (i == RRDOWNSLLEN) {
+ LOGP(DRR, LOGL_NOTICE, "Message unhandled at this "
+ "state.\n");
+ msgb_free(msg);
+ return 0;
+ }
- rc = rrdownstatelist[i].rout(ms, msg);
+ rc = rrdownstatelist[i].rout(ms, msg);
+ } else {
+ /* SAPI 3: find function for current state and message */
+ for (i = 0; i < RRDOWNSLLENS3; i++)
+ if ((msg_type == rrdownstatelists3[i].type)
+ && ((1 << rr->sapi3_state)
+ & rrdownstatelists3[i].states))
+ break;
+ if (i == RRDOWNSLLENS3) {
+ LOGP(DRR, LOGL_NOTICE, "Message unhandled at this "
+ "state.\n");
+ msgb_free(msg);
+ return 0;
+ }
- /* free msgb uless it is forwarded */
- if (rrdownstatelist[i].rout != gsm48_rr_data_req)
+ rc = rrdownstatelists3[i].rout(ms, msg);
+ }
+
+ /* free msgb unless it is forwarded */
+ if (msg_type != GSM48_RR_DATA_REQ)
msgb_free(msg);
return rc;
@@ -5166,7 +5545,7 @@ static void timeout_rr_t3124(void *arg)
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
- return gsm48_send_rsl(ms, RSL_MT_REEST_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_REEST_REQ, nmsg, 0);
todo
}
@@ -5179,7 +5558,7 @@ static int gsm48_rr_tx_hando_access(struct osmocom_ms *ms)
return -ENOMEM;
*msgb_put(nmsg, 1) = rr->hando_ref;
todo burst
- return gsm48_send_rsl(ms, RSL_MT_RAND_ACC_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_RAND_ACC_REQ, nmsg, 0);
}
/* send next channel request in dedicated state */
@@ -5239,8 +5618,7 @@ int gsm48_rr_tx_voice(struct osmocom_ms *ms, struct msgb *msg)
return -ENOTSUP;
}
- return l1ctl_tx_traffic_req(ms, msg, rr->cd_now.chan_nr,
- rr->cd_now.link_id);
+ return l1ctl_tx_traffic_req(ms, msg, rr->cd_now.chan_nr, 0);
}
int gsm48_rr_audio_mode(struct osmocom_ms *ms, uint8_t mode)
diff --git a/Src/osmolib/src/host/layer23/src/mobile/main.c b/Src/osmolib/src/host/layer23/src/mobile/main.c
index 6e743df..89c9b94 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/main.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/main.c
@@ -67,6 +67,9 @@ int mobile_work(struct osmocom_ms *ms);
int mobile_exit(struct osmocom_ms *ms, int force);
+const char *debug_default =
+ "DCS:DNB:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DSS:DLSMS:DPAG:DSUM";
+
const char *openbsc_copyright =
"Copyright (C) 2008-2010 ...\n"
"Contributions by ...\n\n"
@@ -87,7 +90,8 @@ static void print_help()
printf(" -i --gsmtap-ip The destination IP used for GSMTAP.\n");
printf(" -v --vty-port The VTY port number to telnet to. "
"(default %u)\n", vty_port);
- printf(" -d --debug Change debug flags.\n");
+ printf(" -d --debug Change debug flags. default: %s\n",
+ debug_default);
printf(" -D --daemonize Run as daemon\n");
printf(" -m --mncc-sock Disable built-in MNCC handler and "
"offer socket\n");
@@ -147,13 +151,30 @@ void sighandler(int sigset)
fprintf(stderr, "Signal %d received.\n", sigset);
- /* in case there is a lockup during exit */
- signal(SIGINT, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGPIPE, SIG_DFL);
-
- osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
+ switch (sigset) {
+ case SIGINT:
+ /* If another signal is received afterwards, the program
+ * is terminated without finishing shutdown process.
+ */
+ signal(SIGINT, SIG_DFL);
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGPIPE, SIG_DFL);
+ signal(SIGABRT, SIG_DFL);
+ signal(SIGUSR1, SIG_DFL);
+ signal(SIGUSR2, SIG_DFL);
+
+ osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
+ break;
+ case SIGABRT:
+ /* in case of abort, we want to obtain a talloc report
+ * and then return to the caller, who will abort the process
+ */
+ case SIGUSR1:
+ case SIGUSR2:
+ talloc_report_full(l23_ctx, stderr);
+ break;
+ }
}
int main(int argc, char **argv)
@@ -176,11 +197,12 @@ int main(int argc, char **argv)
log_set_all_filter(stderr_target, 1);
l23_ctx = talloc_named_const(NULL, 1, "layer2 context");
+ msgb_set_talloc_ctx(l23_ctx);
handle_options(argc, argv);
if (!debug_set)
- log_parse_category_mask(stderr_target, "DCS:DNB:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM");
+ log_parse_category_mask(stderr_target, debug_default);
log_set_log_level(stderr_target, LOGL_DEBUG);
if (gsmtap_ip) {
@@ -214,6 +236,9 @@ int main(int argc, char **argv)
signal(SIGHUP, sighandler);
signal(SIGTERM, sighandler);
signal(SIGPIPE, sighandler);
+ signal(SIGABRT, sighandler);
+ signal(SIGUSR1, sighandler);
+ signal(SIGUSR2, sighandler);
if (daemonize) {
printf("Running as daemon\n");
@@ -231,5 +256,9 @@ int main(int argc, char **argv)
l23_app_exit();
+ talloc_free(config_file);
+ talloc_free(config_dir);
+ talloc_report_full(l23_ctx, stderr);
+
return 0;
}
diff --git a/Src/osmolib/src/host/layer23/src/mobile/mnccms.c b/Src/osmolib/src/host/layer23/src/mobile/mnccms.c
index c6db1ab..9fdc45f 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/mnccms.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/mnccms.c
@@ -187,7 +187,7 @@ static void mncc_set_bearer(struct osmocom_ms *ms, int8_t speech_ver,
LOGP(DMNCC, LOGL_INFO, " support half rate v1\n");
}
/* if specific speech_ver is given (it must be supported) */
- } else
+ } else
mncc->bearer_cap.speech_ver[i++] = speech_ver;
mncc->bearer_cap.speech_ver[i] = -1; /* end of list */
mncc->bearer_cap.transfer = 0;
@@ -579,7 +579,7 @@ int mncc_call(struct osmocom_ms *ms, char *number)
setup.called.plan = 1; /* ISDN */
strncpy(setup.called.number, number,
sizeof(setup.called.number) - 1);
-
+
/* bearer capability (mandatory) */
mncc_set_bearer(ms, -1, &setup);
if (ms->settings.clir)
diff --git a/Src/osmolib/src/host/layer23/src/mobile/settings.c b/Src/osmolib/src/host/layer23/src/mobile/settings.c
index 592f8a8..e34db7e 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/settings.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/settings.c
@@ -47,8 +47,7 @@ int gsm_settings_init(struct osmocom_ms *ms)
sprintf(set->imeisv, "0000000000000000");
/* SIM type */
-#warning TODO: Enable after SIM reader is available in master branch.
-// set->sim_type = SIM_TYPE_READER;
+ set->sim_type = GSM_SIM_TYPE_READER;
/* test SIM */
strcpy(set->test_imsi, "001010000000000");
@@ -183,7 +182,7 @@ int gsm_random_imei(struct gsm_settings *set)
strcpy(set->imei + 15 - digits, rand + 15 - digits);
strncpy(set->imeisv, set->imei, 15);
-
+
return 0;
}
diff --git a/Src/osmolib/src/host/layer23/src/mobile/subscriber.c b/Src/osmolib/src/host/layer23/src/mobile/subscriber.c
index 6de742a..8ebb173 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/subscriber.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/subscriber.c
@@ -320,9 +320,9 @@ static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
return 0;
/* number */
- if (adn->ton_npi == 1)
+ if (((adn->ton_npi & 0x70) >> 4) == 1)
strcpy(subscr->msisdn, "+");
- if (adn->ton_npi == 2)
+ if (((adn->ton_npi & 0x70) >> 4) == 2)
strcpy(subscr->msisdn, "0");
strncat(subscr->msisdn, sim_decode_bcd(adn->number, adn->len_bcd - 1),
sizeof(subscr->msisdn) - 2);
@@ -332,6 +332,36 @@ static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
return 0;
}
+static int subscr_sim_smsp(struct osmocom_ms *ms, uint8_t *data,
+ uint8_t length)
+{
+ struct gsm_subscriber *subscr = &ms->subscr;
+ struct gsm1111_ef_smsp *smsp;
+
+ if (length < sizeof(*smsp))
+ return -EINVAL;
+ smsp = (struct gsm1111_ef_smsp *) (data + length - sizeof(*smsp));
+
+ /* empty */
+ subscr->sms_sca[0] = '\0';
+
+ /* TS-Service Centre Address */
+ if (!(smsp->par_ind & 0x02) && smsp->ts_sca[0] <= 11) {
+ if (((smsp->ts_sca[1] & 0x70) >> 4) == 1)
+ strcpy(subscr->sms_sca, "+");
+ if (((smsp->ts_sca[1] & 0x70) >> 4) == 2)
+ strcpy(subscr->sms_sca, "0");
+ gsm48_decode_bcd_number(subscr->sms_sca +
+ strlen(subscr->sms_sca), sizeof(subscr->sms_sca)
+ - strlen(subscr->sms_sca), smsp->ts_sca, 1);
+ }
+
+ LOGP(DMM, LOGL_INFO, "received SMSP from SIM (sca=%s)\n",
+ subscr->sms_sca);
+
+ return 0;
+}
+
static int subscr_sim_kc(struct osmocom_ms *ms, uint8_t *data,
uint8_t length)
{
@@ -497,20 +527,22 @@ static struct subscr_sim_file {
uint8_t mandatory;
uint16_t path[MAX_SIM_PATH_LENGTH];
uint16_t file;
+ uint8_t sim_job;
int (*func)(struct osmocom_ms *ms, uint8_t *data,
uint8_t length);
} subscr_sim_files[] = {
- { 1, { 0 }, 0x2fe2, subscr_sim_iccid },
- { 1, { 0x7f20, 0 }, 0x6f07, subscr_sim_imsi },
- { 1, { 0x7f20, 0 }, 0x6f7e, subscr_sim_loci },
- { 0, { 0x7f10, 0 }, 0x6f40, subscr_sim_msisdn },
- { 0, { 0x7f20, 0 }, 0x6f20, subscr_sim_kc },
- { 0, { 0x7f20, 0 }, 0x6f30, subscr_sim_plmnsel },
- { 0, { 0x7f20, 0 }, 0x6f31, subscr_sim_hpplmn },
- { 0, { 0x7f20, 0 }, 0x6f46, subscr_sim_spn },
- { 0, { 0x7f20, 0 }, 0x6f78, subscr_sim_acc },
- { 0, { 0x7f20, 0 }, 0x6f7b, subscr_sim_fplmn },
- { 0, { 0 }, 0, NULL }
+ { 1, { 0 }, 0x2fe2, SIM_JOB_READ_BINARY, subscr_sim_iccid },
+ { 1, { 0x7f20, 0 }, 0x6f07, SIM_JOB_READ_BINARY, subscr_sim_imsi },
+ { 1, { 0x7f20, 0 }, 0x6f7e, SIM_JOB_READ_BINARY, subscr_sim_loci },
+ { 0, { 0x7f20, 0 }, 0x6f20, SIM_JOB_READ_BINARY, subscr_sim_kc },
+ { 0, { 0x7f20, 0 }, 0x6f30, SIM_JOB_READ_BINARY, subscr_sim_plmnsel },
+ { 0, { 0x7f20, 0 }, 0x6f31, SIM_JOB_READ_BINARY, subscr_sim_hpplmn },
+ { 0, { 0x7f20, 0 }, 0x6f46, SIM_JOB_READ_BINARY, subscr_sim_spn },
+ { 0, { 0x7f20, 0 }, 0x6f78, SIM_JOB_READ_BINARY, subscr_sim_acc },
+ { 0, { 0x7f20, 0 }, 0x6f7b, SIM_JOB_READ_BINARY, subscr_sim_fplmn },
+ { 0, { 0x7f10, 0 }, 0x6f40, SIM_JOB_READ_RECORD, subscr_sim_msisdn },
+ { 0, { 0x7f10, 0 }, 0x6f42, SIM_JOB_READ_RECORD, subscr_sim_smsp },
+ { 0, { 0 }, 0, 0, NULL }
};
/* request file from SIM */
@@ -553,7 +585,7 @@ static int subscr_sim_request(struct osmocom_ms *ms)
/* trigger SIM reading */
nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query,
- SIM_JOB_READ_BINARY);
+ sf->sim_job);
if (!nmsg)
return -ENOMEM;
nsh = (struct sim_hdr *) nmsg->data;
@@ -564,6 +596,8 @@ static int subscr_sim_request(struct osmocom_ms *ms)
}
nsh->path[i] = 0; /* end of path */
nsh->file = sf->file;
+ nsh->rec_no = 1;
+ nsh->rec_mode = 0x04;
LOGP(DMM, LOGL_INFO, "Requesting SIM file 0x%04x\n", nsh->file);
sim_job(ms, nmsg);
@@ -1110,6 +1144,14 @@ int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
return 0;
}
+int gsm_subscr_get_key_seq(struct osmocom_ms *ms, struct gsm_subscriber *subscr)
+{
+ if (ms->settings.force_rekey)
+ return 7;
+ else
+ return subscr->key_seq;
+}
+
int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
void (*print)(void *, const char *, ...), void *priv)
{
@@ -1148,6 +1190,9 @@ void gsm_subscr_dump(struct gsm_subscriber *subscr,
print(priv, " Service Provider Name: %s\n", subscr->sim_spn);
if (subscr->msisdn[0])
print(priv, " MSISDN: %s\n", subscr->msisdn);
+ if (subscr->sms_sca[0])
+ print(priv, " SMS Service Center Address: %s\n",
+ subscr->sms_sca);
print(priv, " Status: %s IMSI %s", subscr_ustate_names[subscr->ustate],
(subscr->imsi_attached) ? "attached" : "detached");
if (subscr->tmsi != 0xffffffff)
diff --git a/Src/osmolib/src/host/layer23/src/mobile/support.c b/Src/osmolib/src/host/layer23/src/mobile/support.c
index c4269ac..bfc6180 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/support.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/support.c
@@ -41,7 +41,7 @@ void gsm_support_init(struct osmocom_ms *ms)
/* support of VBS */
sup->vbs = 0; /* no */
/* support of SMS */
- sup->sms_ptp = 0; /* no */
+ sup->sms_ptp = 1; /* no */
/* screening indicator */
sup->ss_ind = 1; /* phase 2 error handling */
/* pseudo synchronised capability */
diff --git a/Src/osmolib/src/host/layer23/src/mobile/transaction.c b/Src/osmolib/src/host/layer23/src/mobile/transaction.c
index 4b66050..45bf2b4 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/transaction.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/transaction.c
@@ -33,6 +33,8 @@
extern void *l23_ctx;
void _gsm48_cc_trans_free(struct gsm_trans *trans);
+void _gsm480_ss_trans_free(struct gsm_trans *trans);
+void _gsm411_sms_trans_free(struct gsm_trans *trans);
struct gsm_trans *trans_find_by_id(struct osmocom_ms *ms,
uint8_t proto, uint8_t trans_id)
@@ -90,14 +92,12 @@ void trans_free(struct gsm_trans *trans)
case GSM48_PDISC_CC:
_gsm48_cc_trans_free(trans);
break;
-#if 0
- case GSM48_PDISC_SS:
- _gsm411_ss_trans_free(trans);
+ case GSM48_PDISC_NC_SS:
+ _gsm480_ss_trans_free(trans);
break;
case GSM48_PDISC_SMS:
_gsm411_sms_trans_free(trans);
break;
-#endif
}
DEBUGP(DCC, "ms %s frees transaction (mem %p)\n", trans->ms->name,
@@ -108,7 +108,7 @@ void trans_free(struct gsm_trans *trans)
talloc_free(trans);
}
-/* allocate an unused transaction ID
+/* allocate an unused transaction ID
* in the given protocol using the ti_flag specified */
int trans_assign_trans_id(struct osmocom_ms *ms,
uint8_t protocol, uint8_t ti_flag)
diff --git a/Src/osmolib/src/host/layer23/src/mobile/vty_interface.c b/Src/osmolib/src/host/layer23/src/mobile/vty_interface.c
index c0a7cef..dc9e09d 100644
--- a/Src/osmolib/src/host/layer23/src/mobile/vty_interface.c
+++ b/Src/osmolib/src/host/layer23/src/mobile/vty_interface.c
@@ -37,6 +37,8 @@
#include <osmocom/bb/mobile/transaction.h>
#include <osmocom/bb/mobile/vty.h>
#include <osmocom/bb/mobile/app_mobile.h>
+#include <osmocom/bb/mobile/gsm480_ss.h>
+#include <osmocom/bb/mobile/gsm411_sms.h>
#include <osmocom/vty/telnet_interface.h>
void *l23_ctx;
@@ -837,6 +839,84 @@ DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
return CMD_SUCCESS;
}
+DEFUN(sms, sms_cmd, "sms MS_NAME NUMBER .LINE",
+ "Send an SMS\nName of MS (see \"show ms\")\nPhone number to send SMS "
+ "(Use digits '0123456789*#abc', and '+' to dial international)\n"
+ "SMS text\n")
+{
+ struct osmocom_ms *ms;
+ struct gsm_settings *set;
+ struct gsm_settings_abbrev *abbrev;
+ char *number, *sms_sca = NULL;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+ set = &ms->settings;
+
+ if (!set->sms_ptp) {
+ vty_out(vty, "SMS not supported by this mobile, please enable "
+ "SMS support%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (ms->subscr.sms_sca[0])
+ sms_sca = ms->subscr.sms_sca;
+ else if (set->sms_sca[0])
+ sms_sca = set->sms_sca;
+
+ if (!sms_sca) {
+ vty_out(vty, "SMS sms-service-center not defined on SIM card, "
+ "please define one at settings.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ number = (char *)argv[1];
+ llist_for_each_entry(abbrev, &set->abbrev, list) {
+ if (!strcmp(number, abbrev->abbrev)) {
+ number = abbrev->number;
+ vty_out(vty, "Using number '%s'%s", number,
+ VTY_NEWLINE);
+ break;
+ }
+ }
+ if (vty_check_number(vty, number))
+ return CMD_WARNING;
+
+ sms_send(ms, sms_sca, number, argv_concat(argv, argc, 2));
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(service, service_cmd, "service MS_NAME (*#06#|*#21#|*#67#|*#61#|*#62#"
+ "|*#002#|*#004#|*xx*number#|*xx#|#xx#|##xx#|STRING|hangup)",
+ "Send a Supplementary Service request\nName of MS (see \"show ms\")\n"
+ "Query IMSI\n"
+ "Query Call Forwarding Unconditional (CFU)\n"
+ "Query Call Forwarding when Busy (CFB)\n"
+ "Query Call Forwarding when No Response (CFNR)\n"
+ "Query Call Forwarding when Not Reachable\n"
+ "Query all Call Forwardings\n"
+ "Query all conditional Call Forwardings\n"
+ "Set and activate Call Forwarding (xx = Service Code, see above)\n"
+ "Activate Call Forwarding (xx = Service Code, see above)\n"
+ "Deactivate Call Forwarding (xx = Service Code, see above)\n"
+ "Erase and deactivate Call Forwarding (xx = Service Code, see above)\n"
+ "Service string "
+ "(Example: '*100#' requests account balace on some networks.)\n"
+ "Hangup existing service connection")
+{
+ struct osmocom_ms *ms;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+
+ ss_send(ms, argv[1], 0);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(test_reselection, test_reselection_cmd, "test re-selection NAME",
"Manually trigger cell re-selection\nName of MS (see \"show ms\")")
{
@@ -1208,12 +1288,21 @@ static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
else
if (!hide_default)
vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
+ if (set->sms_sca[0])
+ vty_out(vty, " sms-service-center %s%s", set->sms_sca,
+ VTY_NEWLINE);
+ else
+ if (!hide_default)
+ vty_out(vty, " no sms-service-center%s", VTY_NEWLINE);
if (!hide_default || set->cw)
vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ",
VTY_NEWLINE);
if (!hide_default || set->auto_answer)
vty_out(vty, " %sauto-answer%s",
(set->auto_answer) ? "" : "no ", VTY_NEWLINE);
+ if (!hide_default || set->force_rekey)
+ vty_out(vty, " %sforce-rekey%s",
+ (set->force_rekey) ? "" : "no ", VTY_NEWLINE);
if (!hide_default || set->clip)
vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ",
VTY_NEWLINE);
@@ -1569,6 +1658,37 @@ DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
return CMD_SUCCESS;
}
+DEFUN(cfg_ms_sms_sca, cfg_ms_sms_sca_cmd, "sms-service-center NUMBER",
+ "Use Service center address for outgoing SMS\nNumber of service center "
+ "(Use digits '0123456789*#abc', and '+' to dial international)")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ const char *number = argv[0];
+
+ if ((strlen(number) > 20 && number[0] != '+') || strlen(number) > 21) {
+ vty_out(vty, "Number too long%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (vty_check_number(vty, number))
+ return CMD_WARNING;
+
+ strcpy(set->sms_sca, number);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_no_sms_sca, cfg_ms_no_sms_sca_cmd, "no sms-service-center",
+ NO_STR "Use Service center address for outgoing SMS")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->sms_sca[0] = '\0';
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
NO_STR "Disallow waiting calls")
{
@@ -1613,6 +1733,28 @@ DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
return CMD_SUCCESS;
}
+DEFUN(cfg_no_force_rekey, cfg_ms_no_force_rekey_cmd, "no force-rekey",
+ NO_STR "Disable key renew forcing after every event")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->force_rekey = 0;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_force_rekey, cfg_ms_force_rekey_cmd, "force-rekey",
+ "Enable key renew forcing after every event")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->force_rekey = 1;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
"Force caller ID presentation")
{
@@ -2624,6 +2766,8 @@ int ms_vty_init(void)
install_element(ENABLE_NODE, &call_cmd);
install_element(ENABLE_NODE, &call_retr_cmd);
install_element(ENABLE_NODE, &call_dtmf_cmd);
+ install_element(ENABLE_NODE, &sms_cmd);
+ install_element(ENABLE_NODE, &service_cmd);
install_element(ENABLE_NODE, &test_reselection_cmd);
install_element(ENABLE_NODE, &delete_forbidden_plmn_cmd);
@@ -2657,10 +2801,14 @@ int ms_vty_init(void)
install_element(MS_NODE, &cfg_ms_imei_random_cmd);
install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
+ install_element(MS_NODE, &cfg_ms_no_sms_sca_cmd);
+ install_element(MS_NODE, &cfg_ms_sms_sca_cmd);
install_element(MS_NODE, &cfg_ms_cw_cmd);
install_element(MS_NODE, &cfg_ms_no_cw_cmd);
install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
+ install_element(MS_NODE, &cfg_ms_force_rekey_cmd);
+ install_element(MS_NODE, &cfg_ms_no_force_rekey_cmd);
install_element(MS_NODE, &cfg_ms_clip_cmd);
install_element(MS_NODE, &cfg_ms_clir_cmd);
install_element(MS_NODE, &cfg_ms_no_clip_cmd);
diff --git a/Src/osmolib/src/host/osmocon/git-version-gen b/Src/osmolib/src/host/osmocon/git-version-gen
index 652fac6..652fac6 100644..100755
--- a/Src/osmolib/src/host/osmocon/git-version-gen
+++ b/Src/osmolib/src/host/osmocon/git-version-gen
diff --git a/Src/osmolib/src/host/osmocon/memdump_convert.pl b/Src/osmolib/src/host/osmocon/memdump_convert.pl
index 3d18a0b..3d18a0b 100644..100755
--- a/Src/osmolib/src/host/osmocon/memdump_convert.pl
+++ b/Src/osmolib/src/host/osmocon/memdump_convert.pl
diff --git a/Src/osmolib/src/host/osmocon/osmocon.c b/Src/osmolib/src/host/osmocon/osmocon.c
index 189984f..66f2462 100644
--- a/Src/osmolib/src/host/osmocon/osmocon.c
+++ b/Src/osmolib/src/host/osmocon/osmocon.c
@@ -123,6 +123,7 @@ enum dnload_mode {
MODE_C155,
MODE_ROMLOAD,
MODE_MTK,
+ MODE_INVALID,
};
struct dnload {
@@ -267,7 +268,7 @@ int read_file(const char *filename)
}
rc = fstat(fd, &st);
- if (st.st_size > MAX_DNLOAD_SIZE) {
+ if ((st.st_size > MAX_DNLOAD_SIZE) && (dnload.mode != MODE_ROMLOAD)) {
fprintf(stderr, "The maximum file size is 64kBytes (%u bytes)\n",
MAX_DNLOAD_SIZE);
return -EFBIG;
@@ -1184,7 +1185,7 @@ static int parse_mode(const char *arg)
else if (!strcasecmp(arg, "mtk"))
return MODE_MTK;
- return -1;
+ return MODE_INVALID;
}
#define HELP_TEXT \
@@ -1236,7 +1237,8 @@ static int un_tool_read(struct osmo_fd *fd, unsigned int flags)
c += rc;
}
- length = ntohs(*(uint16_t*)buf);
+ memcpy(&length, buf, sizeof length);
+ length = ntohs(length);
c = 0;
while(c < length) {
@@ -1412,7 +1414,7 @@ int main(int argc, char **argv)
break;
case 'm':
dnload.mode = parse_mode(optarg);
- if (dnload.mode < 0)
+ if (dnload.mode == MODE_INVALID)
usage(argv[0]);
break;
case 's':
diff --git a/Src/osmolib/src/host/osmocon/osmoload.c b/Src/osmolib/src/host/osmocon/osmoload.c
index 8a0b21c..2d55839 100644
--- a/Src/osmolib/src/host/osmocon/osmoload.c
+++ b/Src/osmolib/src/host/osmocon/osmoload.c
@@ -186,7 +186,7 @@ static void osmoload_osmo_hexdump(const uint8_t *data, unsigned int len)
static void
loader_send_request(struct msgb *msg) {
int rc;
- u_int16_t len = htons(msg->len);
+ uint16_t len = htons(msg->len);
if(osmoload.print_requests) {
printf("Sending %d bytes:\n", msg->len);
@@ -453,7 +453,7 @@ loader_handle_reply(struct msgb *msg) {
static int
loader_read_cb(struct osmo_fd *fd, unsigned int flags) {
struct msgb *msg;
- u_int16_t len;
+ uint16_t len;
int rc;
msg = msgb_alloc(MSGB_MAX, "loader");
diff --git a/Src/osmolib/src/host/rita_pll/mtk_pll.pl b/Src/osmolib/src/host/rita_pll/mtk_pll.pl
index ff931c5..ff931c5 100644..100755
--- a/Src/osmolib/src/host/rita_pll/mtk_pll.pl
+++ b/Src/osmolib/src/host/rita_pll/mtk_pll.pl
diff --git a/Src/osmolib/src/host/rita_pll/rita_pll.pl b/Src/osmolib/src/host/rita_pll/rita_pll.pl
index b5b0944..b5b0944 100644..100755
--- a/Src/osmolib/src/host/rita_pll/rita_pll.pl
+++ b/Src/osmolib/src/host/rita_pll/rita_pll.pl
diff --git a/Src/osmolib/src/shared/libosmocore/.gitignore b/Src/osmolib/src/shared/libosmocore/.gitignore
index b4d657f..82e43e3 100644
--- a/Src/osmolib/src/shared/libosmocore/.gitignore
+++ b/Src/osmolib/src/shared/libosmocore/.gitignore
@@ -7,6 +7,8 @@ Makefile.in
*.la
*.pc
aclocal.m4
+acinclude.m4
+aminclude.am
m4/*.m4
autom4te.cache
config.h*
@@ -31,16 +33,40 @@ Doxyfile.codec
.tarball-version
.version
+#gnu autotest
+tests/package.m4
+tests/atconfig
+tests/atlocal
+tests/osmo-test
+tests/package.m4
+tests/testsuite
+tests/testsuite.dir/
+tests/testsuite.log
+
tests/sms/sms_test
tests/timer/timer_test
tests/msgfile/msgfile_test
tests/ussd/ussd_test
tests/smscb/smscb_test
+tests/bits/bitrev_test
+tests/a5/a5_test
+tests/auth/milenage_test
+tests/conv/conv_test
+tests/lapd/lapd_test
+tests/gsm0808/gsm0808_test
utils/osmo-arfcn
+utils/osmo-auc-gen
doc/codec
doc/core
doc/vty
doc/gsm
doc/html.tar
+
+src/crc*gen.c
+include/osmocom/core/crc*gen.h
+
+
+# vi files
+*.sw?
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc16gen.h b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc16gen.h
new file mode 100644
index 0000000..09101d4
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc16gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc16gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC16GEN_H__
+#define __OSMO_CRC16GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc16gen.h
+ * \file Osmocom generic CRC routines (for max 16 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 16 bits */
+struct osmo_crc16gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint16_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint16_t init; /*!< \brief Initialization value of the CRC state */
+ uint16_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint16_t osmo_crc16gen_compute_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc16gen_check_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc16gen_set_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC16GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc32gen.h b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc32gen.h
new file mode 100644
index 0000000..fe84f6c
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc32gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc32gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC32GEN_H__
+#define __OSMO_CRC32GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc32gen.h
+ * \file Osmocom generic CRC routines (for max 32 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 32 bits */
+struct osmo_crc32gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint32_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint32_t init; /*!< \brief Initialization value of the CRC state */
+ uint32_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint32_t osmo_crc32gen_compute_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc32gen_check_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc32gen_set_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC32GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc64gen.h b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc64gen.h
new file mode 100644
index 0000000..9ffc056
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc64gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc64gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC64GEN_H__
+#define __OSMO_CRC64GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc64gen.h
+ * \file Osmocom generic CRC routines (for max 64 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 64 bits */
+struct osmo_crc64gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint64_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint64_t init; /*!< \brief Initialization value of the CRC state */
+ uint64_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint64_t osmo_crc64gen_compute_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc64gen_check_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc64gen_set_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC64GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc8gen.h b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc8gen.h
new file mode 100644
index 0000000..99e5164
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/include/osmocom/core/crc8gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc8gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC8GEN_H__
+#define __OSMO_CRC8GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc8gen.h
+ * \file Osmocom generic CRC routines (for max 8 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 8 bits */
+struct osmo_crc8gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint8_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint8_t init; /*!< \brief Initialization value of the CRC state */
+ uint8_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint8_t osmo_crc8gen_compute_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc8gen_check_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc8gen_set_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC8GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/src/crc16gen.c b/Src/osmolib/src/shared/libosmocore/build-host/src/crc16gen.c
new file mode 100644
index 0000000..4d4b78f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/src/crc16gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc16gen.c
+ *
+ * Generic CRC routines (for max 16 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc16gen.c
+ * \file Osmocom generic CRC routines (for max 16 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc16gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint16_t
+osmo_crc16gen_compute_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint16_t poly = code->poly;
+ uint16_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint16_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc16gen_check_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint16_t crc;
+ int i;
+
+ crc = osmo_crc16gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc16gen_set_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint16_t crc;
+ int i;
+
+ crc = osmo_crc16gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/src/crc32gen.c b/Src/osmolib/src/shared/libosmocore/build-host/src/crc32gen.c
new file mode 100644
index 0000000..765ff4f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/src/crc32gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc32gen.c
+ *
+ * Generic CRC routines (for max 32 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc32gen.c
+ * \file Osmocom generic CRC routines (for max 32 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc32gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint32_t
+osmo_crc32gen_compute_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint32_t poly = code->poly;
+ uint32_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint32_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc32gen_check_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint32_t crc;
+ int i;
+
+ crc = osmo_crc32gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc32gen_set_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint32_t crc;
+ int i;
+
+ crc = osmo_crc32gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/src/crc64gen.c b/Src/osmolib/src/shared/libosmocore/build-host/src/crc64gen.c
new file mode 100644
index 0000000..8ce9dd6
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/src/crc64gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc64gen.c
+ *
+ * Generic CRC routines (for max 64 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc64gen.c
+ * \file Osmocom generic CRC routines (for max 64 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc64gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint64_t
+osmo_crc64gen_compute_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint64_t poly = code->poly;
+ uint64_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint64_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc64gen_check_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint64_t crc;
+ int i;
+
+ crc = osmo_crc64gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc64gen_set_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint64_t crc;
+ int i;
+
+ crc = osmo_crc64gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/src/crc8gen.c b/Src/osmolib/src/shared/libosmocore/build-host/src/crc8gen.c
new file mode 100644
index 0000000..0756a10
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/src/crc8gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc8gen.c
+ *
+ * Generic CRC routines (for max 8 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc8gen.c
+ * \file Osmocom generic CRC routines (for max 8 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc8gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint8_t
+osmo_crc8gen_compute_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint8_t poly = code->poly;
+ uint8_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint8_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc8gen_check_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint8_t crc;
+ int i;
+
+ crc = osmo_crc8gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc8gen_set_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint8_t crc;
+ int i;
+
+ crc = osmo_crc8gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/a5/a5_test b/Src/osmolib/src/shared/libosmocore/build-host/tests/a5/a5_test
new file mode 100755
index 0000000..c169f80
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/a5/a5_test
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# a5_test - temporary wrapper script for .libs/a5_test
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The a5_test program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/tests/a5; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file a5_test.o ../../src/.libs/libosmocore.so ../../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4'
+ notinst_deplibs=' ../../src/libosmocore.la ../../src/gsm/libosmogsm.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="printf %s\\n"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "a5_test:a5_test:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "a5_test:a5_test:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "a5_test:a5_test:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program=lt-'a5_test'
+ progdir="$thisdir/.libs"
+
+ if test ! -f "$progdir/$program" ||
+ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+ test "X$file" != "X$progdir/$program"; }; then
+
+ file="$$-$program"
+
+ if test ! -d "$progdir"; then
+ mkdir "$progdir"
+ else
+ rm -f "$progdir/$file"
+ fi
+
+ # relink executable if necessary
+ if test -n "$relink_command"; then
+ if relink_command_output=`eval $relink_command 2>&1`; then :
+ else
+ printf %s\n "$relink_command_output" >&2
+ rm -f "$progdir/$file"
+ exit 1
+ fi
+ fi
+
+ mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+ { rm -f "$progdir/$program";
+ mv -f "$progdir/$file" "$progdir/$program"; }
+ rm -f "$progdir/$file"
+ fi
+
+ if test -f "$progdir/$program"; then
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/atconfig b/Src/osmolib/src/shared/libosmocore/build-host/tests/atconfig
new file mode 100644
index 0000000..b8266f3
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/atconfig
@@ -0,0 +1,20 @@
+# Configurable variable values for building test suites.
+# Generated by ./config.status.
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# The test suite will define top_srcdir=/../.. etc.
+at_testdir='tests'
+abs_builddir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-host/tests'
+at_srcdir='../../tests'
+abs_srcdir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-host/../tests'
+at_top_srcdir='../..'
+abs_top_srcdir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-host/..'
+at_top_build_prefix='../'
+abs_top_builddir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-host'
+
+# Backward compatibility with Autotest <= 2.59b:
+at_top_builddir=$at_top_build_prefix
+
+AUTOTEST_PATH='tests'
+
+SHELL=${CONFIG_SHELL-'/bin/bash'}
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/auth/milenage_test b/Src/osmolib/src/shared/libosmocore/build-host/tests/auth/milenage_test
new file mode 100755
index 0000000..b6bef92
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/auth/milenage_test
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# milenage_test - temporary wrapper script for .libs/milenage_test
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The milenage_test program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/tests/auth; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file milenage_test.o ../../src/.libs/libosmocore.so ../../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4'
+ notinst_deplibs=' ../../src/libosmocore.la ../../src/gsm/libosmogsm.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="printf %s\\n"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "milenage_test:milenage_test:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "milenage_test:milenage_test:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "milenage_test:milenage_test:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program=lt-'milenage_test'
+ progdir="$thisdir/.libs"
+
+ if test ! -f "$progdir/$program" ||
+ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+ test "X$file" != "X$progdir/$program"; }; then
+
+ file="$$-$program"
+
+ if test ! -d "$progdir"; then
+ mkdir "$progdir"
+ else
+ rm -f "$progdir/$file"
+ fi
+
+ # relink executable if necessary
+ if test -n "$relink_command"; then
+ if relink_command_output=`eval $relink_command 2>&1`; then :
+ else
+ printf %s\n "$relink_command_output" >&2
+ rm -f "$progdir/$file"
+ exit 1
+ fi
+ fi
+
+ mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+ { rm -f "$progdir/$program";
+ mv -f "$progdir/$file" "$progdir/$program"; }
+ rm -f "$progdir/$file"
+ fi
+
+ if test -f "$progdir/$program"; then
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/bits/bitrev_test b/Src/osmolib/src/shared/libosmocore/build-host/tests/bits/bitrev_test
index b9f073e..9d063d1 100644..100755
--- a/Src/osmolib/src/shared/libosmocore/build-host/tests/bits/bitrev_test
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/bits/bitrev_test
@@ -31,7 +31,7 @@ DUALCASE=1; export DUALCASE # for MKS sh
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-relink_command="(cd /home/tom/imsi-catcher-detection/Src/osmocom-bb/src/shared/libosmocore/build-host/tests/bits; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/home/tom/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/local/bin; export PATH; gcc -g -O2 -o \$progdir/\$file bitrev_test.o ../../src/.libs/libosmocore.so -Wl,-rpath -Wl,/home/tom/imsi-catcher-detection/Src/osmocom-bb/src/shared/libosmocore/build-host/src/.libs)"
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/tests/bits; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file bitrev_test.o ../../src/.libs/libosmocore.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs)"
# This environment variable determines our operation mode.
if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/conv/conv_test b/Src/osmolib/src/shared/libosmocore/build-host/tests/conv/conv_test
new file mode 100755
index 0000000..d0ca113
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/conv/conv_test
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# conv_test - temporary wrapper script for .libs/conv_test
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The conv_test program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/tests/conv; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file conv_test.o ../../src/.libs/libosmocore.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4'
+ notinst_deplibs=' ../../src/libosmocore.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="printf %s\\n"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "conv_test:conv_test:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "conv_test:conv_test:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "conv_test:conv_test:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program=lt-'conv_test'
+ progdir="$thisdir/.libs"
+
+ if test ! -f "$progdir/$program" ||
+ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+ test "X$file" != "X$progdir/$program"; }; then
+
+ file="$$-$program"
+
+ if test ! -d "$progdir"; then
+ mkdir "$progdir"
+ else
+ rm -f "$progdir/$file"
+ fi
+
+ # relink executable if necessary
+ if test -n "$relink_command"; then
+ if relink_command_output=`eval $relink_command 2>&1`; then :
+ else
+ printf %s\n "$relink_command_output" >&2
+ rm -f "$progdir/$file"
+ exit 1
+ fi
+ fi
+
+ mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+ { rm -f "$progdir/$program";
+ mv -f "$progdir/$file" "$progdir/$program"; }
+ rm -f "$progdir/$file"
+ fi
+
+ if test -f "$progdir/$program"; then
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/gsm0808/gsm0808_test b/Src/osmolib/src/shared/libosmocore/build-host/tests/gsm0808/gsm0808_test
new file mode 100755
index 0000000..62f2291
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/gsm0808/gsm0808_test
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# gsm0808_test - temporary wrapper script for .libs/gsm0808_test
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The gsm0808_test program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/tests/gsm0808; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file gsm0808_test.o ../../src/.libs/libosmocore.so ../../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4'
+ notinst_deplibs=' ../../src/libosmocore.la ../../src/gsm/libosmogsm.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="printf %s\\n"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "gsm0808_test:gsm0808_test:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "gsm0808_test:gsm0808_test:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "gsm0808_test:gsm0808_test:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program=lt-'gsm0808_test'
+ progdir="$thisdir/.libs"
+
+ if test ! -f "$progdir/$program" ||
+ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+ test "X$file" != "X$progdir/$program"; }; then
+
+ file="$$-$program"
+
+ if test ! -d "$progdir"; then
+ mkdir "$progdir"
+ else
+ rm -f "$progdir/$file"
+ fi
+
+ # relink executable if necessary
+ if test -n "$relink_command"; then
+ if relink_command_output=`eval $relink_command 2>&1`; then :
+ else
+ printf %s\n "$relink_command_output" >&2
+ rm -f "$progdir/$file"
+ exit 1
+ fi
+ fi
+
+ mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+ { rm -f "$progdir/$program";
+ mv -f "$progdir/$file" "$progdir/$program"; }
+ rm -f "$progdir/$file"
+ fi
+
+ if test -f "$progdir/$program"; then
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/tests/lapd/lapd_test b/Src/osmolib/src/shared/libosmocore/build-host/tests/lapd/lapd_test
new file mode 100755
index 0000000..a4bb289
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/tests/lapd/lapd_test
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# lapd_test - temporary wrapper script for .libs/lapd_test
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The lapd_test program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/tests/lapd; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file lapd_test.o ../../src/.libs/libosmocore.so ../../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4'
+ notinst_deplibs=' ../../src/libosmocore.la ../../src/gsm/libosmogsm.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="printf %s\\n"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "lapd_test:lapd_test:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "lapd_test:lapd_test:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "lapd_test:lapd_test:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program=lt-'lapd_test'
+ progdir="$thisdir/.libs"
+
+ if test ! -f "$progdir/$program" ||
+ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+ test "X$file" != "X$progdir/$program"; }; then
+
+ file="$$-$program"
+
+ if test ! -d "$progdir"; then
+ mkdir "$progdir"
+ else
+ rm -f "$progdir/$file"
+ fi
+
+ # relink executable if necessary
+ if test -n "$relink_command"; then
+ if relink_command_output=`eval $relink_command 2>&1`; then :
+ else
+ printf %s\n "$relink_command_output" >&2
+ rm -f "$progdir/$file"
+ exit 1
+ fi
+ fi
+
+ mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+ { rm -f "$progdir/$program";
+ mv -f "$progdir/$file" "$progdir/$program"; }
+ rm -f "$progdir/$file"
+ fi
+
+ if test -f "$progdir/$program"; then
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-arfcn b/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-arfcn
index 30facd4..f4b3fc1 100644..100755
--- a/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-arfcn
+++ b/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-arfcn
@@ -31,7 +31,7 @@ DUALCASE=1; export DUALCASE # for MKS sh
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-relink_command="(cd /home/tom/imsi-catcher-detection/Src/osmocom-bb/src/shared/libosmocore/build-host/utils; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/home/tom/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/local/bin; export PATH; gcc -g -O2 -o \$progdir/\$file osmo-arfcn.o ../src/.libs/libosmocore.so ../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/imsi-catcher-detection/Src/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/imsi-catcher-detection/Src/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/utils; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file osmo-arfcn.o ../src/.libs/libosmocore.so ../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
# This environment variable determines our operation mode.
if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
diff --git a/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-auc-gen b/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-auc-gen
new file mode 100755
index 0000000..69bb486
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-host/utils/osmo-auc-gen
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# osmo-auc-gen - temporary wrapper script for .libs/osmo-auc-gen
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The osmo-auc-gen program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/utils; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin; export PATH; gcc -g -O2 -o \$progdir/\$file osmo-auc-gen.o ../src/.libs/libosmocore.so ../src/gsm/.libs/libosmogsm.so -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/.libs -Wl,-rpath -Wl,/home/tom/test/osmocom-bb/src/shared/libosmocore/build-host/src/gsm/.libs)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4'
+ notinst_deplibs=' ../src/libosmocore.la ../src/gsm/libosmogsm.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="printf %s\\n"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "osmo-auc-gen:osmo-auc-gen:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "osmo-auc-gen:osmo-auc-gen:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "osmo-auc-gen:osmo-auc-gen:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program=lt-'osmo-auc-gen'
+ progdir="$thisdir/.libs"
+
+ if test ! -f "$progdir/$program" ||
+ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+ test "X$file" != "X$progdir/$program"; }; then
+
+ file="$$-$program"
+
+ if test ! -d "$progdir"; then
+ mkdir "$progdir"
+ else
+ rm -f "$progdir/$file"
+ fi
+
+ # relink executable if necessary
+ if test -n "$relink_command"; then
+ if relink_command_output=`eval $relink_command 2>&1`; then :
+ else
+ printf %s\n "$relink_command_output" >&2
+ rm -f "$progdir/$file"
+ exit 1
+ fi
+ fi
+
+ mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+ { rm -f "$progdir/$program";
+ mv -f "$progdir/$file" "$progdir/$program"; }
+ rm -f "$progdir/$file"
+ fi
+
+ if test -f "$progdir/$program"; then
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc16gen.h b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc16gen.h
new file mode 100644
index 0000000..09101d4
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc16gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc16gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC16GEN_H__
+#define __OSMO_CRC16GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc16gen.h
+ * \file Osmocom generic CRC routines (for max 16 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 16 bits */
+struct osmo_crc16gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint16_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint16_t init; /*!< \brief Initialization value of the CRC state */
+ uint16_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint16_t osmo_crc16gen_compute_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc16gen_check_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc16gen_set_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC16GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc32gen.h b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc32gen.h
new file mode 100644
index 0000000..fe84f6c
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc32gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc32gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC32GEN_H__
+#define __OSMO_CRC32GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc32gen.h
+ * \file Osmocom generic CRC routines (for max 32 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 32 bits */
+struct osmo_crc32gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint32_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint32_t init; /*!< \brief Initialization value of the CRC state */
+ uint32_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint32_t osmo_crc32gen_compute_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc32gen_check_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc32gen_set_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC32GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc64gen.h b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc64gen.h
new file mode 100644
index 0000000..9ffc056
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc64gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc64gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC64GEN_H__
+#define __OSMO_CRC64GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc64gen.h
+ * \file Osmocom generic CRC routines (for max 64 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 64 bits */
+struct osmo_crc64gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint64_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint64_t init; /*!< \brief Initialization value of the CRC state */
+ uint64_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint64_t osmo_crc64gen_compute_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc64gen_check_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc64gen_set_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC64GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc8gen.h b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc8gen.h
new file mode 100644
index 0000000..99e5164
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/include/osmocom/core/crc8gen.h
@@ -0,0 +1,59 @@
+/*
+ * crc8gen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRC8GEN_H__
+#define __OSMO_CRC8GEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc8gen.h
+ * \file Osmocom generic CRC routines (for max 8 bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max 8 bits */
+struct osmo_crc8gen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uint8_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uint8_t init; /*!< \brief Initialization value of the CRC state */
+ uint8_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uint8_t osmo_crc8gen_compute_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len);
+int osmo_crc8gen_check_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crc8gen_set_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRC8GEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/src/crc16gen.c b/Src/osmolib/src/shared/libosmocore/build-target/src/crc16gen.c
new file mode 100644
index 0000000..4d4b78f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/src/crc16gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc16gen.c
+ *
+ * Generic CRC routines (for max 16 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc16gen.c
+ * \file Osmocom generic CRC routines (for max 16 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc16gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint16_t
+osmo_crc16gen_compute_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint16_t poly = code->poly;
+ uint16_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint16_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc16gen_check_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint16_t crc;
+ int i;
+
+ crc = osmo_crc16gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc16gen_set_bits(const struct osmo_crc16gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint16_t crc;
+ int i;
+
+ crc = osmo_crc16gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/src/crc32gen.c b/Src/osmolib/src/shared/libosmocore/build-target/src/crc32gen.c
new file mode 100644
index 0000000..765ff4f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/src/crc32gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc32gen.c
+ *
+ * Generic CRC routines (for max 32 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc32gen.c
+ * \file Osmocom generic CRC routines (for max 32 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc32gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint32_t
+osmo_crc32gen_compute_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint32_t poly = code->poly;
+ uint32_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint32_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc32gen_check_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint32_t crc;
+ int i;
+
+ crc = osmo_crc32gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc32gen_set_bits(const struct osmo_crc32gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint32_t crc;
+ int i;
+
+ crc = osmo_crc32gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/src/crc64gen.c b/Src/osmolib/src/shared/libosmocore/build-target/src/crc64gen.c
new file mode 100644
index 0000000..8ce9dd6
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/src/crc64gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc64gen.c
+ *
+ * Generic CRC routines (for max 64 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc64gen.c
+ * \file Osmocom generic CRC routines (for max 64 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc64gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint64_t
+osmo_crc64gen_compute_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint64_t poly = code->poly;
+ uint64_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint64_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc64gen_check_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint64_t crc;
+ int i;
+
+ crc = osmo_crc64gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc64gen_set_bits(const struct osmo_crc64gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint64_t crc;
+ int i;
+
+ crc = osmo_crc64gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/src/crc8gen.c b/Src/osmolib/src/shared/libosmocore/build-target/src/crc8gen.c
new file mode 100644
index 0000000..0756a10
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/src/crc8gen.c
@@ -0,0 +1,120 @@
+/*
+ * crc8gen.c
+ *
+ * Generic CRC routines (for max 8 bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crc8gen.c
+ * \file Osmocom generic CRC routines (for max 8 bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crc8gen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uint8_t
+osmo_crc8gen_compute_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len)
+{
+ const uint8_t poly = code->poly;
+ uint8_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uint8_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crc8gen_check_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uint8_t crc;
+ int i;
+
+ crc = osmo_crc8gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crc8gen_set_bits(const struct osmo_crc8gen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uint8_t crc;
+ int i;
+
+ crc = osmo_crc8gen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/build-target/tests/atconfig b/Src/osmolib/src/shared/libosmocore/build-target/tests/atconfig
new file mode 100644
index 0000000..4989dee
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/build-target/tests/atconfig
@@ -0,0 +1,20 @@
+# Configurable variable values for building test suites.
+# Generated by ./config.status.
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# The test suite will define top_srcdir=/../.. etc.
+at_testdir='tests'
+abs_builddir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-target/tests'
+at_srcdir='../../tests'
+abs_srcdir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-target/../tests'
+at_top_srcdir='../..'
+abs_top_srcdir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-target/..'
+at_top_build_prefix='../'
+abs_top_builddir='/home/tom/imsi-catcher-detection/Src/osmolib/src/shared/libosmocore/build-target'
+
+# Backward compatibility with Autotest <= 2.59b:
+at_top_builddir=$at_top_build_prefix
+
+AUTOTEST_PATH='tests'
+
+SHELL=${CONFIG_SHELL-'/bin/bash'}
diff --git a/Src/osmolib/src/shared/libosmocore/configure.ac b/Src/osmolib/src/shared/libosmocore/configure.ac
index 52ab850..ec79a92 100644
--- a/Src/osmolib/src/shared/libosmocore/configure.ac
+++ b/Src/osmolib/src/shared/libosmocore/configure.ac
@@ -3,6 +3,7 @@ AC_INIT([libosmocore],
[openbsc-devel@lists.openbsc.org])
AM_INIT_AUTOMAKE([dist-bzip2])
+AC_CONFIG_TESTDIR(tests)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -19,6 +20,10 @@ AC_CONFIG_MACRO_DIR([m4])
dnl checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h syslog.h ctype.h)
+# for src/conv.c
+AC_FUNC_ALLOCA
+AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
+AC_SUBST(LIBRARY_DL)
AC_PATH_PROG(DOXYGEN,doxygen,false)
AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false)
@@ -134,6 +139,7 @@ then
AC_DEFINE([PANIC_INFLOOP],[1],[Use infinite loop on panic rather than fprintf/abort])
fi
+
AC_OUTPUT(
libosmocore.pc
libosmocodec.pc
@@ -158,6 +164,11 @@ AC_OUTPUT(
tests/ussd/Makefile
tests/smscb/Makefile
tests/bits/Makefile
+ tests/a5/Makefile
+ tests/auth/Makefile
+ tests/conv/Makefile
+ tests/lapd/Makefile
+ tests/gsm0808/Makefile
utils/Makefile
Doxyfile.core
Doxyfile.gsm
diff --git a/Src/osmolib/src/shared/libosmocore/debian/rules b/Src/osmolib/src/shared/libosmocore/debian/rules
index 15f78f2..15f78f2 100644..100755
--- a/Src/osmolib/src/shared/libosmocore/debian/rules
+++ b/Src/osmolib/src/shared/libosmocore/debian/rules
diff --git a/Src/osmolib/src/shared/libosmocore/git-version-gen b/Src/osmolib/src/shared/libosmocore/git-version-gen
index 42cf3d2..42cf3d2 100644..100755
--- a/Src/osmolib/src/shared/libosmocore/git-version-gen
+++ b/Src/osmolib/src/shared/libosmocore/git-version-gen
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/Makefile.am b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/Makefile.am
index f131269..1df111a 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/Makefile.am
@@ -2,8 +2,11 @@ osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h bits.h \
bitvec.h statistics.h utils.h socket.h \
gsmtap.h write_queue.h prim.h \
logging.h rate_ctr.h gsmtap_util.h \
- crc16.h panic.h process.h \
- backtrace.h conv.h application.h
+ crc16.h panic.h process.h linuxrbtree.h \
+ backtrace.h conv.h application.h \
+ crcgen.h crc8gen.h crc16gen.h crc32gen.h crc64gen.h
+
+noinst_HEADERS = timer_compat.h
if ENABLE_PLUGIN
osmocore_HEADERS += plugin.h
@@ -22,3 +25,7 @@ osmocore_HEADERS += serial.h
endif
osmocoredir = $(includedir)/osmocom/core
+
+crc%gen.h: crcXXgen.h.tpl
+ @echo " SED $< -> $@"
+ @sed -e's/XX/$*/g' $< > $@
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/conv.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/conv.h
index db3058c..e76a5c6 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/conv.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/conv.h
@@ -35,25 +35,52 @@
#include <osmocom/core/bits.h>
-/*! \brief structure describing a given convolutional code */
+/*! \brief possibe termination types
+ *
+ * The termination type will determine which state the encoder/decoder
+ * can start/end with. This is mostly taken care of in the high level API
+ * call. So if you use the low level API, you must take care of making the
+ * proper calls yourself.
+ */
+enum osmo_conv_term {
+ CONV_TERM_FLUSH = 0, /*!< \brief Flush encoder state */
+ CONV_TERM_TRUNCATION, /*!< \brief Direct truncation */
+ CONV_TERM_TAIL_BITING, /*!< \brief Tail biting */
+};
+
+/*! \brief structure describing a given convolutional code
+ *
+ * The only required fields are N,K and the next_output/next_state arrays. The
+ * other can be left to default value of zero depending on what the code does.
+ * If 'len' is left at 0 then only the low level API can be used.
+ */
struct osmo_conv_code {
- int N;
- int K;
- int len;
+ int N; /*!< \brief Inverse of code rate */
+ int K; /*!< \brief Constraint length */
+ int len; /*!< \brief # of data bits */
+
+ enum osmo_conv_term term; /*!< \brief Termination type */
- const uint8_t (*next_output)[2];
- const uint8_t (*next_state)[2];
+ const uint8_t (*next_output)[2];/*!< \brief Next output array */
+ const uint8_t (*next_state)[2]; /*!< \brief Next state array */
- const uint8_t *next_term_output;
- const uint8_t *next_term_state;
+ const uint8_t *next_term_output;/*!< \brief Flush termination output */
+ const uint8_t *next_term_state; /*!< \brief Flush termination state */
- const int *puncture;
+ const int *puncture; /*!< \brief Punctured bits indexes */
};
+/* Common */
+
+int osmo_conv_get_input_length(const struct osmo_conv_code *code, int len);
+int osmo_conv_get_output_length(const struct osmo_conv_code *code, int len);
+
+
/* Encoding */
/* Low level API */
+
/*! \brief convolutional encoder state */
struct osmo_conv_encoder {
const struct osmo_conv_code *code; /*!< \brief for which code? */
@@ -64,9 +91,11 @@ struct osmo_conv_encoder {
void osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
const struct osmo_conv_code *code);
+void osmo_conv_encode_load_state(struct osmo_conv_encoder *encoder,
+ const ubit_t *input);
int osmo_conv_encode_raw(struct osmo_conv_encoder *encoder,
const ubit_t *input, ubit_t *output, int n);
-int osmo_conv_encode_finish(struct osmo_conv_encoder *encoder, ubit_t *output);
+int osmo_conv_encode_flush(struct osmo_conv_encoder *encoder, ubit_t *output);
/* All-in-one */
int osmo_conv_encode(const struct osmo_conv_code *code,
@@ -76,10 +105,10 @@ int osmo_conv_encode(const struct osmo_conv_code *code,
/* Decoding */
/* Low level API */
+
/*! \brief convolutional decoder state */
struct osmo_conv_decoder {
- /*! \brief description of convolutional code */
- const struct osmo_conv_code *code;
+ const struct osmo_conv_code *code; /*!< \brief for which code? */
int n_states; /*!< \brief number of states */
@@ -88,22 +117,24 @@ struct osmo_conv_decoder {
int o_idx; /*!< \brief output index */
int p_idx; /*!< \brief puncture index */
- unsigned int *ae; /*!< \brief accumulater error */
+ unsigned int *ae; /*!< \brief accumulated error */
unsigned int *ae_next; /*!< \brief next accumulated error (tmp in scan) */
uint8_t *state_history; /*!< \brief state history [len][n_states] */
};
void osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
- const struct osmo_conv_code *code, int len);
-void osmo_conv_decode_reset(struct osmo_conv_decoder *decoder);
+ const struct osmo_conv_code *code,
+ int len, int start_state);
+void osmo_conv_decode_reset(struct osmo_conv_decoder *decoder, int start_state);
+void osmo_conv_decode_rewind(struct osmo_conv_decoder *decoder);
void osmo_conv_decode_deinit(struct osmo_conv_decoder *decoder);
int osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
const sbit_t *input, int n);
-int osmo_conv_decode_finish(struct osmo_conv_decoder *decoder,
- const sbit_t *input);
+int osmo_conv_decode_flush(struct osmo_conv_decoder *decoder,
+ const sbit_t *input);
int osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
- ubit_t *output, int has_finish);
+ ubit_t *output, int has_flush, int end_state);
/* All-in-one */
int osmo_conv_decode(const struct osmo_conv_code *code,
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/crcXXgen.h.tpl b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/crcXXgen.h.tpl
new file mode 100644
index 0000000..b411276
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/crcXXgen.h.tpl
@@ -0,0 +1,59 @@
+/*
+ * crcXXgen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRCXXGEN_H__
+#define __OSMO_CRCXXGEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crcXXgen.h
+ * \file Osmocom generic CRC routines (for max XX bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max XX bits */
+struct osmo_crcXXgen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uintXX_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uintXX_t init; /*!< \brief Initialization value of the CRC state */
+ uintXX_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uintXX_t osmo_crcXXgen_compute_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len);
+int osmo_crcXXgen_check_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crcXXgen_set_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! }@ */
+
+#endif /* __OSMO_CRCXXGEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap.h
index 236b25a..5dc869d 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap.h
@@ -14,6 +14,21 @@
#include <stdint.h>
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* The GSMTAP format definition is maintained in libosmocore,
+ * specifically the latest version can always be obtained from
+ * http://cgit.osmocom.org/cgit/libosmocore/tree/include/osmocom/core/gsmtap.h
+ *
+ * If you want to introduce new protocol/burst/channel types or extend
+ * GSMTAP in any way, please contact the GSMTAP maintainer at either the
+ * public openbsc@lists.osmocom.org mailing list, or privately at
+ * Harald Welte <laforge@gnumonks.org>.
+ *
+ * Your cooperation ensures that all projects will use the same GSMTAP
+ * definitions and remain compatible with each other.
+ */
+
#define GSMTAP_VERSION 0x02
#define GSMTAP_TYPE_UM 0x01
@@ -22,6 +37,12 @@
#define GSMTAP_TYPE_SIM 0x04
#define GSMTAP_TYPE_TETRA_I1 0x05 /* tetra air interface */
#define GSMTAP_TYPE_TETRA_I1_BURST 0x06 /* tetra air interface */
+#define GSMTAP_TYPE_WMX_BURST 0x07 /* WiMAX burst */
+#define GSMTAP_TYPE_GB_LLC 0x08 /* GPRS Gb interface: LLC */
+#define GSMTAP_TYPE_GB_SNDCP 0x09 /* GPRS Gb interface: SNDCP */
+#define GSMTAP_TYPE_GMR1_UM 0x0a /* GMR-1 L2 packets */
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_UM_BURST */
#define GSMTAP_BURST_UNKNOWN 0x00
@@ -34,6 +55,15 @@
#define GSMTAP_BURST_DUMMY 0x07
#define GSMTAP_BURST_ACCESS 0x08
#define GSMTAP_BURST_NONE 0x09
+/* WiMAX bursts */
+#define GSMTAP_BURST_CDMA_CODE 0x10 /* WiMAX CDMA Code Attribute burst */
+#define GSMTAP_BURST_FCH 0x11 /* WiMAX FCH burst */
+#define GSMTAP_BURST_FFB 0x12 /* WiMAX Fast Feedback burst */
+#define GSMTAP_BURST_PDU 0x13 /* WiMAX PDU burst */
+#define GSMTAP_BURST_HACK 0x14 /* WiMAX HARQ ACK burst */
+#define GSMTAP_BURST_PHY_ATTRIBUTES 0x15 /* WiMAX PHY Attributes burst */
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_UM */
#define GSMTAP_CHANNEL_UNKNOWN 0x00
@@ -47,8 +77,15 @@
#define GSMTAP_CHANNEL_SDCCH8 0x08
#define GSMTAP_CHANNEL_TCH_F 0x09
#define GSMTAP_CHANNEL_TCH_H 0x0a
+#define GSMTAP_CHANNEL_PACCH 0x0b
+#define GSMTAP_CHANNEL_CBCH52 0x0c
+#define GSMTAP_CHANNEL_PDCH 0x0d
+#define GSMTAP_CHANNEL_PTCCH 0x0e
+#define GSMTAP_CHANNEL_CBCH51 0x0f
#define GSMTAP_CHANNEL_ACCH 0x80
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
/* sub-types for TYPE_TETRA_AIR */
#define GSMTAP_TETRA_BSCH 0x01
#define GSMTAP_TETRA_AACH 0x02
@@ -59,6 +96,30 @@
#define GSMTAP_TETRA_STCH 0x07
#define GSMTAP_TETRA_TCH_F 0x08
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* sub-types for TYPE_GMR1_UM */
+#define GSMTAP_GMR1_UNKNOWN 0x00
+#define GSMTAP_GMR1_BCCH 0x01
+#define GSMTAP_GMR1_CCCH 0x02 /* either AGCH or PCH */
+#define GSMTAP_GMR1_PCH 0x03
+#define GSMTAP_GMR1_AGCH 0x04
+#define GSMTAP_GMR1_BACH 0x05
+#define GSMTAP_GMR1_RACH 0x06
+#define GSMTAP_GMR1_CBCH 0x07
+#define GSMTAP_GMR1_SDCCH 0x08
+#define GSMTAP_GMR1_TACCH 0x09
+#define GSMTAP_GMR1_GBCH 0x0a
+
+#define GSMTAP_GMR1_SACCH 0x01 /* to be combined with _TCH{6,9} */
+#define GSMTAP_GMR1_FACCH 0x02 /* to be combines with _TCH{3,6,9} */
+#define GSMTAP_GMR1_DKAB 0x03 /* to be combined with _TCH3 */
+#define GSMTAP_GMR1_TCH3 0x10
+#define GSMTAP_GMR1_TCH6 0x14
+#define GSMTAP_GMR1_TCH9 0x18
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
/* flags for the ARFCN */
#define GSMTAP_ARFCN_F_PCS 0x8000
#define GSMTAP_ARFCN_F_UPLINK 0x4000
@@ -67,6 +128,7 @@
/* IANA-assigned well-known UDP port for GSMTAP messages */
#define GSMTAP_UDP_PORT 4729
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
struct gsmtap_hdr {
uint8_t version; /* version, set to 0x01 currently */
uint8_t hdr_len; /* length in number of 32bit words */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap_util.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap_util.h
index 36cbf53..5609381 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap_util.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/gsmtap_util.h
@@ -12,6 +12,10 @@
uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t rsl_link_id);
+struct msgb *gsmtap_makemsg_ex(uint8_t type, uint16_t arfcn, uint8_t ts, uint8_t chan_type,
+ uint8_t ss, uint32_t fn, int8_t signal_dbm,
+ uint8_t snr, const uint8_t *data, unsigned int len);
+
struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
uint8_t ss, uint32_t fn, int8_t signal_dbm,
uint8_t snr, const uint8_t *data, unsigned int len);
@@ -40,6 +44,11 @@ int gsmtap_source_add_sink(struct gsmtap_inst *gti);
int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg);
+int gsmtap_send_ex(struct gsmtap_inst *gti, uint8_t type, uint16_t arfcn, uint8_t ts,
+ uint8_t chan_type, uint8_t ss, uint32_t fn,
+ int8_t signal_dbm, uint8_t snr, const uint8_t *data,
+ unsigned int len);
+
int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
uint8_t chan_type, uint8_t ss, uint32_t fn,
int8_t signal_dbm, uint8_t snr, const uint8_t *data,
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/linuxrbtree.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/linuxrbtree.h
new file mode 100644
index 0000000..44e00a1
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/linuxrbtree.h
@@ -0,0 +1,160 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ linux/include/linux/rbtree.h
+
+ To use rbtrees you'll have to implement your own insert and search cores.
+ This will avoid us to use callbacks and to drop drammatically performances.
+ I know it's not the cleaner way, but in C (not in C++) to get
+ performances and genericity...
+
+ Some example of insert and search follows here. The search is a plain
+ normal search over an ordered tree. The insert instead must be implemented
+ int two steps: as first thing the code must insert the element in
+ order as a red leaf in the tree, then the support library function
+ rb_insert_color() must be called. Such function will do the
+ not trivial work to rebalance the rbtree if necessary.
+
+-----------------------------------------------------------------------
+static inline struct page * rb_search_page_cache(struct inode * inode,
+ unsigned long offset)
+{
+ struct rb_node * n = inode->i_rb_page_cache.rb_node;
+ struct page * page;
+
+ while (n)
+ {
+ page = rb_entry(n, struct page, rb_page_cache);
+
+ if (offset < page->offset)
+ n = n->rb_left;
+ else if (offset > page->offset)
+ n = n->rb_right;
+ else
+ return page;
+ }
+ return NULL;
+}
+
+static inline struct page * __rb_insert_page_cache(struct inode * inode,
+ unsigned long offset,
+ struct rb_node * node)
+{
+ struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
+ struct rb_node * parent = NULL;
+ struct page * page;
+
+ while (*p)
+ {
+ parent = *p;
+ page = rb_entry(parent, struct page, rb_page_cache);
+
+ if (offset < page->offset)
+ p = &(*p)->rb_left;
+ else if (offset > page->offset)
+ p = &(*p)->rb_right;
+ else
+ return page;
+ }
+
+ rb_link_node(node, parent, p);
+
+ return NULL;
+}
+
+static inline struct page * rb_insert_page_cache(struct inode * inode,
+ unsigned long offset,
+ struct rb_node * node)
+{
+ struct page * ret;
+ if ((ret = __rb_insert_page_cache(inode, offset, node)))
+ goto out;
+ rb_insert_color(node, &inode->i_rb_page_cache);
+ out:
+ return ret;
+}
+-----------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_RBTREE_H
+#define _LINUX_RBTREE_H
+
+#include <stdlib.h>
+
+struct rb_node
+{
+ unsigned long rb_parent_color;
+#define RB_RED 0
+#define RB_BLACK 1
+ struct rb_node *rb_right;
+ struct rb_node *rb_left;
+} __attribute__((aligned(sizeof(long))));
+ /* The alignment might seem pointless, but allegedly CRIS needs it */
+
+struct rb_root
+{
+ struct rb_node *rb_node;
+};
+
+
+#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
+#define rb_color(r) ((r)->rb_parent_color & 1)
+#define rb_is_red(r) (!rb_color(r))
+#define rb_is_black(r) rb_color(r)
+#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
+#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+ rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
+}
+static inline void rb_set_color(struct rb_node *rb, int color)
+{
+ rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
+}
+
+#define RB_ROOT { NULL, }
+#define rb_entry(ptr, type, member) container_of(ptr, type, member)
+
+#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
+#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
+#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
+
+extern void rb_insert_color(struct rb_node *, struct rb_root *);
+extern void rb_erase(struct rb_node *, struct rb_root *);
+
+/* Find logical next and previous nodes in a tree */
+extern struct rb_node *rb_next(const struct rb_node *);
+extern struct rb_node *rb_prev(const struct rb_node *);
+extern struct rb_node *rb_first(const struct rb_root *);
+extern struct rb_node *rb_last(const struct rb_root *);
+
+/* Fast replacement of a single node without remove/rebalance/add/rebalance */
+extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
+ struct rb_root *root);
+
+static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
+ struct rb_node ** rb_link)
+{
+ node->rb_parent_color = (unsigned long )parent;
+ node->rb_left = node->rb_right = NULL;
+
+ *rb_link = node;
+}
+
+#endif /* _LINUX_RBTREE_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/logging.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/logging.h
index 72e4c93..043a850 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/logging.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/logging.h
@@ -62,12 +62,13 @@ void logp(int subsys, char *file, int line, int cont, const char *format, ...) _
/* logging levels defined by the library itself */
#define DLGLOBAL -1
-#define DLLAPDM -2
+#define DLLAPD -2
#define DLINP -3
#define DLMUX -4
#define DLMI -5
#define DLMIB -6
-#define OSMO_NUM_DLIB 6
+#define DLSMS -7
+#define OSMO_NUM_DLIB 7
struct log_category {
uint8_t loglevel;
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/msgb.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/msgb.h
index 9f46e6c..e465ec2 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/msgb.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/msgb.h
@@ -312,6 +312,32 @@ static inline void msgb_reserve(struct msgb *msg, int len)
msg->tail += len;
}
+/*! \brief Trim the msgb to a given absolute length
+ * \param[in] msg message buffer
+ * \param[in] len new total length of buffer
+ * \returns 0 in case of success, negative in case of error
+ */
+static inline int msgb_trim(struct msgb *msg, int len)
+{
+ if (len > msg->data_len)
+ return -1;
+
+ msg->len = len;
+ msg->tail = msg->data + len;
+
+ return 0;
+}
+
+/*! \brief Trim the msgb to a given layer3 length
+ * \pram[in] msg message buffer
+ * \param[in] l3len new layer3 length
+ * \returns 0 in case of success, negative in case of error
+ */
+static inline int msgb_l3trim(struct msgb *msg, int l3len)
+{
+ return msgb_trim(msg, (msg->l3h - msg->data) + l3len);
+}
+
/*! \brief Allocate message buffer with specified headroom
* \param[in] size size in bytes, including headroom
* \param[in] headroom headroom in bytes
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/prim.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/prim.h
index 2e60c46..b1026fe 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/prim.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/prim.h
@@ -10,6 +10,9 @@
#include <stdint.h>
#include <osmocom/core/msgb.h>
+#define OSMO_PRIM(prim, op) ((prim << 8) | (op & 0xFF))
+#define OSMO_PRIM_HDR(oph) OSMO_PRIM((oph)->primitive, (oph)->operation)
+
/*! \brief primitive operation */
enum osmo_prim_operation {
PRIM_OP_REQUEST, /*!< \brief request */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer.h
index 8f8c826..30f558b 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer.h
@@ -32,6 +32,7 @@
#include <sys/time.h>
#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/linuxrbtree.h>
/**
* Timer management:
@@ -51,11 +52,10 @@
*/
/*! \brief A structure representing a single instance of a timer */
struct osmo_timer_list {
- struct llist_head entry; /*!< \brief linked list header */
+ struct rb_node node; /*!< \brief rb-tree node header */
+ struct llist_head list; /*!< \brief internal list header */
struct timeval timeout; /*!< \brief expiration time */
unsigned int active : 1; /*!< \brief is it active? */
- unsigned int handled : 1; /*!< \brief did we already handle it */
- unsigned int in_list : 1; /*!< \brief is it in the global list? */
void (*cb)(void*); /*!< \brief call-back called at timeout */
void *data; /*!< \brief user data for callback */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer_compat.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer_compat.h
new file mode 100644
index 0000000..209e84a
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/timer_compat.h
@@ -0,0 +1,79 @@
+/*
+ * (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/*! \defgroup timer Osmocom timers
+ * @{
+ */
+
+/*! \file timer_compat.h
+ * \brief Compatibility header with some helpers
+ */
+
+#ifndef TIMER_COMPAT_H
+#define TIMER_COMPAT_H
+
+
+/* Convenience macros for operations on timevals.
+ NOTE: `timercmp' does not work for >= or <=. */
+
+#ifndef timerisset
+# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#endif
+
+#ifndef timerclear
+# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+#endif
+
+#ifndef timercmp
+# define timercmp(a, b, CMP) \
+ (((a)->tv_sec == (b)->tv_sec) ? \
+ ((a)->tv_usec CMP (b)->tv_usec) : \
+ ((a)->tv_sec CMP (b)->tv_sec))
+#endif
+
+#ifndef timeradd
+# define timeradd(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+ if ((result)->tv_usec >= 1000000) \
+ { \
+ ++(result)->tv_sec; \
+ (result)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#endif
+
+#ifndef timersub
+# define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
+
+/*! }@ */
+
+#endif /* TIMER_COMPAT_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/utils.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/utils.h
index 940c25f..f1843d9 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/core/utils.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/core/utils.h
@@ -34,7 +34,8 @@ int osmo_hexparse(const char *str, uint8_t *b, int max_len);
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
char *osmo_hexdump(const unsigned char *buf, int len);
-char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len);
+char *osmo_hexdump_nospc(const unsigned char *buf, int len);
+char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len) __attribute__((__deprecated__));
#define osmo_static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/Makefile.am b/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/Makefile.am
index 7ce69fd..e4a6e53 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/Makefile.am
@@ -1,3 +1,3 @@
-osmocrypt_HEADERS = gprs_cipher.h
+osmocrypt_HEADERS = gprs_cipher.h auth.h
osmocryptdir = $(includedir)/osmocom/crypt
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/auth.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/auth.h
new file mode 100644
index 0000000..30e16e8
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/crypt/auth.h
@@ -0,0 +1,90 @@
+#ifndef _OSMOCRYPTO_AUTH_H
+#define _OSMOCRYPTO_AUTH_H
+
+#include <stdint.h>
+
+#include <osmocom/core/linuxlist.h>
+
+/*! \brief Authentication Type */
+enum osmo_sub_auth_type {
+ OSMO_AUTH_TYPE_NONE = 0x00,
+ OSMO_AUTH_TYPE_GSM = 0x01,
+ OSMO_AUTH_TYPE_UMTS = 0x02,
+};
+
+/*! \brief Authentication Algorithm */
+enum osmo_auth_algo {
+ OSMO_AUTH_ALG_NONE,
+ OSMO_AUTH_ALG_COMP128v1,
+ OSMO_AUTH_ALG_COMP128v2,
+ OSMO_AUTH_ALG_COMP128v3,
+ OSMO_AUTH_ALG_XOR,
+ OSMO_AUTH_ALG_MILENAGE,
+ _OSMO_AUTH_ALG_NUM,
+};
+
+/*! \brief permanent (secret) subscriber auth data */
+struct osmo_sub_auth_data {
+ enum osmo_sub_auth_type type;
+ enum osmo_auth_algo algo;
+ union {
+ struct {
+ uint8_t opc[16];
+ uint8_t k[16];
+ uint8_t amf[2];
+ uint64_t sqn;
+ } umts;
+ struct {
+ uint8_t ki[16];
+ } gsm;
+ } u;
+};
+
+/* data structure describing a computed auth vector, generated by AuC */
+struct osmo_auth_vector {
+ uint8_t rand[16];
+ uint8_t autn[16];
+ uint8_t ck[16];
+ uint8_t ik[16];
+ uint8_t res[16];
+ uint8_t res_len;
+ uint8_t kc[8];
+ uint8_t sres[4];
+ uint32_t auth_types; /*!< bitmask of OSMO_AUTH_TYPE_* */
+};
+
+/* \brief An implementation of an authentication algorithm */
+struct osmo_auth_impl {
+ struct llist_head list;
+ enum osmo_auth_algo algo;
+ const char *name;
+ unsigned int priority;
+
+ int (*gen_vec)(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *_rand);
+
+ int (*gen_vec_auts)(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *rand_auts, const uint8_t *auts,
+ const uint8_t *_rand);
+};
+
+int osmo_auth_gen_vec(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud, const uint8_t *_rand);
+
+int osmo_auth_gen_vec_auts(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *rand_auts, const uint8_t *auts,
+ const uint8_t *_rand);
+
+int osmo_auth_register(struct osmo_auth_impl *impl);
+
+int osmo_auth_load(const char *path);
+
+int osmo_auth_supported(enum osmo_auth_algo algo);
+
+const char *osmo_auth_alg_name(enum osmo_auth_algo alg);
+enum osmo_auth_algo osmo_auth_alg_parse(const char *name);
+
+#endif /* _OSMOCRYPTO_AUTH_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/Makefile.am b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/Makefile.am
index 90f19bc..fc1abfe 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/Makefile.am
@@ -1,6 +1,7 @@
osmogsm_HEADERS = a5.h comp128.h gsm0808.h gsm48_ie.h mncc.h rxlev_stat.h \
gsm0480.h gsm48.h gsm_utils.h rsl.h tlv.h abis_nm.h \
- sysinfo.h prim.h gsm0502.h lapdm.h
+ sysinfo.h prim.h gsm0502.h lapd_core.h lapdm.h \
+ gsm0411_utils.h gsm0411_smc.h gsm0411_smr.h
SUBDIRS = protocol
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/a5.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/a5.h
index 2c630e5..7e6a17c 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/a5.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/a5.h
@@ -27,6 +27,18 @@
#include <osmocom/core/bits.h>
+/*! \defgroup a5 GSM A5 ciphering algorithm
+ * @{
+ */
+
+/*! \file gsm/a5.h
+ * \brief Osmocom GSM A5 ciphering algorithm header
+ */
+
+/*! \brief Converts a frame number into the 22 bit number used in A5/x
+ * \param[in] fn The true framenumber
+ * \return 22 bit word
+ */
static inline uint32_t
osmo_a5_fn_count(uint32_t fn)
{
@@ -42,8 +54,10 @@ osmo_a5_fn_count(uint32_t fn)
* - fn is the _real_ GSM frame number.
* (converted internally to fn_count)
*/
-void osmo_a5(int n, uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
-void osmo_a5_1(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
-void osmo_a5_2(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
+void osmo_a5(int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
+void osmo_a5_1(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
+void osmo_a5_2(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
+
+/*! }@ */
#endif /* __OSMO_A5_H__ */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/comp128.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/comp128.h
index c37808f..e4587d4 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/comp128.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/comp128.h
@@ -16,7 +16,7 @@
* sres : uint8_t [4]
* kc : uint8_t [8]
*/
-void comp128(uint8_t *ki, uint8_t *srand, uint8_t *sres, uint8_t *kc);
+void comp128(const uint8_t *ki, const uint8_t *srand, uint8_t *sres, uint8_t *kc);
#endif /* __COMP128_H__ */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smc.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smc.h
new file mode 100644
index 0000000..e1508a2
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smc.h
@@ -0,0 +1,62 @@
+#ifndef _GSM0411_SMC_H
+#define _GSM0411_SMC_H
+
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+
+#define GSM411_MMSMS_EST_REQ 0x310
+#define GSM411_MMSMS_EST_IND 0x312
+#define GSM411_MMSMS_EST_CNF 0x311
+#define GSM411_MMSMS_REL_REQ 0x320
+#define GSM411_MMSMS_REL_IND 0x322
+#define GSM411_MMSMS_DATA_REQ 0x330
+#define GSM411_MMSMS_DATA_IND 0x332
+#define GSM411_MMSMS_UNIT_DATA_REQ 0x340
+#define GSM411_MMSMS_UNIT_DATA_IND 0x342
+#define GSM411_MMSMS_ERR_IND 0x372
+
+#define GSM411_MNSMS_ABORT_REQ 0x101
+#define GSM411_MNSMS_DATA_REQ 0x102
+#define GSM411_MNSMS_DATA_IND 0x103
+#define GSM411_MNSMS_EST_REQ 0x104
+#define GSM411_MNSMS_EST_IND 0x105
+#define GSM411_MNSMS_ERROR_IND 0x106
+#define GSM411_MNSMS_REL_REQ 0x107
+
+struct gsm411_smc_inst {
+ int network; /* is this a MO (0) or MT (1) transfer */
+ int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg);
+ int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type);
+
+ enum gsm411_cp_state cp_state;
+ struct osmo_timer_list cp_timer;
+ struct msgb *cp_msg; /* store pending message */
+ int cp_rel; /* store pending release */
+ int cp_retx; /* retry counter */
+ int cp_max_retr; /* maximum retry */
+ int cp_tc1; /* timer value TC1* */
+
+};
+
+extern const struct value_string gsm411_cp_cause_strs[];
+
+/* init a new instance */
+void gsm411_smc_init(struct gsm411_smc_inst *inst, int network,
+ int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg),
+ int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type));
+
+/* clear instance */
+void gsm411_smc_clear(struct gsm411_smc_inst *inst);
+
+/* message from upper layer */
+int gsm411_smc_send(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg);
+
+/* message from lower layer */
+int gsm411_smc_recv(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type);
+
+#endif /* _GSM0411_SMC_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smr.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smr.h
new file mode 100644
index 0000000..5ea8584
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_smr.h
@@ -0,0 +1,45 @@
+#ifndef _GSM0411_SMR_H
+#define _GSM0411_SMR_H
+
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+
+#define GSM411_SM_RL_DATA_REQ 0x401
+#define GSM411_SM_RL_DATA_IND 0x402
+#define GSM411_SM_RL_MEM_AVAIL_REQ 0x403
+#define GSM411_SM_RL_MEM_AVAIL_IND 0x404
+#define GSM411_SM_RL_REPORT_REQ 0x405
+#define GSM411_SM_RL_REPORT_IND 0x406
+
+struct gsm411_smr_inst {
+ int network; /* is this a MO (0) or MT (1) transfer */
+ int (*rl_recv) (struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg);
+ int (*mn_send) (struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg);
+
+ enum gsm411_rp_state rp_state;
+ struct osmo_timer_list rp_timer;
+};
+
+extern const struct value_string gsm411_rp_cause_strs[];
+
+/* init a new instance */
+void gsm411_smr_init(struct gsm411_smr_inst *inst, int network,
+ int (*rl_recv) (struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg),
+ int (*mn_send) (struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg));
+
+/* clear instance */
+void gsm411_smr_clear(struct gsm411_smr_inst *inst);
+
+/* message from upper layer */
+int gsm411_smr_send(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg);
+
+/* message from lower layer */
+int gsm411_smr_recv(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg);
+
+#endif /* _GSM0411_SMR_H */
+
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_utils.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_utils.h
new file mode 100644
index 0000000..d29ca63
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0411_utils.h
@@ -0,0 +1,36 @@
+#ifndef _GSM0411_UTILS_H
+#define _GSM0411_UTILS_H
+
+/* Turn int into semi-octet representation: 98 => 0x89 */
+uint8_t gsm411_bcdify(uint8_t value);
+
+/* Turn semi-octet representation into int: 0x89 => 98 */
+uint8_t gsm411_unbcdify(uint8_t value);
+
+struct msgb *gsm411_msgb_alloc(void);
+
+/* Generate 03.40 TP-SCTS */
+void gsm340_gen_scts(uint8_t *scts, time_t time);
+
+/* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */
+time_t gsm340_scts(uint8_t *scts);
+
+/* decode validity period. return minutes */
+unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp);
+
+/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
+enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs);
+
+/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */
+int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type,
+ uint8_t plan, const char *number);
+
+/* Prefix msg with a RP header */
+int gsm411_push_rp_header(struct msgb *msg, uint8_t rp_msg_type,
+ uint8_t rp_msg_ref);
+
+/* Prefix msg with a 04.08/04.11 CP header */
+int gsm411_push_cp_header(struct msgb *msg, uint8_t proto, uint8_t trans,
+ uint8_t msg_type);
+
+#endif /* _GSM0411_UTILS_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0808.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0808.h
index 38d88ef..5380dd9 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0808.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm0808.h
@@ -30,7 +30,8 @@ struct msgb *gsm0808_create_clear_command(uint8_t reason);
struct msgb *gsm0808_create_clear_complete(void);
struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id);
struct msgb *gsm0808_create_cipher_reject(uint8_t cause);
-struct msgb *gsm0808_create_classmark_update(const uint8_t *classmark, uint8_t length);
+struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
+ const uint8_t *cm3, uint8_t cm3_len);
struct msgb *gsm0808_create_sapi_reject(uint8_t link_id);
struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
uint8_t chosen_channel, uint8_t encr_alg_id,
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm48_ie.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm48_ie.h
index f4fce25..2e57642 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm48_ie.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/gsm48_ie.h
@@ -108,7 +108,7 @@ int gsm48_encode_more(struct msgb *msg);
struct gsm_sysinfo_freq {
/* if the frequency included in the sysinfo */
uint8_t mask;
-};
+} __attribute__ ((packed));
/* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd,
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapd_core.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapd_core.h
new file mode 100644
index 0000000..0f4e889
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapd_core.h
@@ -0,0 +1,171 @@
+#ifndef _OSMOCOM_LAPD_H
+#define _OSMOCOM_LAPD_H
+
+#include <stdint.h>
+
+#include <osmocom/core/timer.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/prim.h>
+
+/*! \defgroup lapd LAPD implementation common part
+ * @{
+ */
+
+/*! \file lapd.h */
+
+/* primitive related sutff */
+
+/*! \brief LAPD related primitives (L2<->L3 SAP)*/
+enum osmo_dl_prim {
+ PRIM_DL_UNIT_DATA, /*!< \brief DL-UNIT-DATA */
+ PRIM_DL_DATA, /*!< \brief DL-DATA */
+ PRIM_DL_EST, /*!< \brief DL-ESTABLISH */
+ PRIM_DL_REL, /*!< \brief DL-RLEEASE */
+ PRIM_DL_SUSP, /*!< \brief DL-SUSPEND */
+ PRIM_DL_RES, /*!< \brief DL-RESUME */
+ PRIM_DL_RECON, /*!< \brief DL-RECONNECT */
+ PRIM_MDL_ERROR, /*!< \brief MDL-ERROR */
+};
+
+/* Uses the same values as RLL, so no conversion for GSM is required. */
+#define MDL_CAUSE_T200_EXPIRED 0x01
+#define MDL_CAUSE_REEST_REQ 0x02
+#define MDL_CAUSE_UNSOL_UA_RESP 0x03
+#define MDL_CAUSE_UNSOL_DM_RESP 0x04
+#define MDL_CAUSE_UNSOL_DM_RESP_MF 0x05
+#define MDL_CAUSE_UNSOL_SPRV_RESP 0x06
+#define MDL_CAUSE_SEQ_ERR 0x07
+#define MDL_CAUSE_UFRM_INC_PARAM 0x08
+#define MDL_CAUSE_SFRM_INC_PARAM 0x09
+#define MDL_CAUSE_IFRM_INC_MBITS 0x0a
+#define MDL_CAUSE_IFRM_INC_LEN 0x0b
+#define MDL_CAUSE_FRM_UNIMPL 0x0c
+#define MDL_CAUSE_SABM_MF 0x0d
+#define MDL_CAUSE_SABM_INFO_NOTALL 0x0e
+#define MDL_CAUSE_FRMR 0x0f
+
+/*! \brief for MDL-ERROR.ind */
+struct mdl_error_ind_param {
+ uint8_t cause; /*!< \brief generic cause value */
+};
+
+/*! \brief for DL-REL.req */
+struct dl_rel_req_param {
+ uint8_t mode; /*!< \brief release mode */
+};
+
+/*! \brief primitive header for LAPD DL-SAP primitives */
+struct osmo_dlsap_prim {
+ struct osmo_prim_hdr oph; /*!< \brief generic primitive header */
+ union {
+ struct mdl_error_ind_param error_ind;
+ struct dl_rel_req_param rel_req;
+ } u; /*!< \brief request-specific data */
+};
+
+/*! \brief LAPD mode/role */
+enum lapd_mode {
+ LAPD_MODE_USER, /*!< \brief behave like user */
+ LAPD_MODE_NETWORK, /*!< \brief behave like network */
+};
+
+/*! \brief LAPD state (Figure B.2/Q.921)*/
+enum lapd_state {
+ LAPD_STATE_NULL = 0,
+ LAPD_STATE_TEI_UNASS,
+ LAPD_STATE_ASS_TEI_WAIT,
+ LAPD_STATE_EST_TEI_WAIT,
+ LAPD_STATE_IDLE,
+ LAPD_STATE_SABM_SENT,
+ LAPD_STATE_DISC_SENT,
+ LAPD_STATE_MF_EST,
+ LAPD_STATE_TIMER_RECOV,
+};
+
+/*! \brief LAPD message format (I / S / U) */
+enum lapd_format {
+ LAPD_FORM_UKN = 0,
+ LAPD_FORM_I,
+ LAPD_FORM_S,
+ LAPD_FORM_U,
+};
+
+/*! \brief LAPD message context */
+struct lapd_msg_ctx {
+ struct lapd_datalink *dl;
+ int n201;
+ /* address */
+ uint8_t cr;
+ uint8_t sapi;
+ uint8_t tei;
+ uint8_t lpd;
+ /* control */
+ uint8_t format;
+ uint8_t p_f; /* poll / final bit */
+ uint8_t n_send;
+ uint8_t n_recv;
+ uint8_t s_u; /* S or repectivly U function bits */
+ /* length */
+ int length;
+ uint8_t more;
+};
+
+struct lapd_cr_ent {
+ uint8_t cmd;
+ uint8_t resp;
+};
+
+struct lapd_history {
+ struct msgb *msg; /* message to be sent / NULL, if histoy is empty */
+ int more; /* if message is fragmented */
+};
+
+/*! \brief LAPD datalink */
+struct lapd_datalink {
+ int (*send_dlsap)(struct osmo_dlsap_prim *dp,
+ struct lapd_msg_ctx *lctx);
+ int (*send_ph_data_req)(struct lapd_msg_ctx *lctx, struct msgb *msg);
+ struct {
+ /*! \brief filled-in once we set the lapd_mode above */
+ struct lapd_cr_ent loc2rem;
+ struct lapd_cr_ent rem2loc;
+ } cr;
+ enum lapd_mode mode; /*!< \brief current mode of link */
+ int use_sabme; /*!< \brief use SABME instead of SABM */
+ int reestablish; /*!< \brief enable reestablish support */
+ int n200, n200_est_rel; /*!< \brief number of retranmissions */
+ struct lapd_msg_ctx lctx; /*!< \brief LAPD context */
+ int maxf; /*!< \brief maximum frame size (after defragmentation) */
+ uint8_t k; /*!< \brief maximum number of unacknowledged frames */
+ uint8_t v_range; /*!< \brief range of sequence numbers */
+ uint8_t v_send; /*!< \brief seq nr of next I frame to be transmitted */
+ uint8_t v_ack; /*!< \brief last frame ACKed by peer */
+ uint8_t v_recv; /*!< \brief seq nr of next I frame expected to be received */
+ uint32_t state; /*!< \brief LAPD state (\ref lapd_state) */
+ int seq_err_cond; /*!< \brief condition of sequence error */
+ uint8_t own_busy; /*!< \brief receiver busy on our side */
+ uint8_t peer_busy; /*!< \brief receiver busy on remote side */
+ int t200_sec, t200_usec; /*!< \brief retry timer (default 1 sec) */
+ int t203_sec, t203_usec; /*!< \brief retry timer (default 10 secs) */
+ struct osmo_timer_list t200; /*!< \brief T200 timer */
+ struct osmo_timer_list t203; /*!< \brief T203 timer */
+ uint8_t retrans_ctr; /*!< \brief re-transmission counter */
+ struct llist_head tx_queue; /*!< \brief frames to L1 */
+ struct llist_head send_queue; /*!< \brief frames from L3 */
+ struct msgb *send_buffer; /*!< \brief current frame transmitting */
+ int send_out; /*!< \brief how much was sent from send_buffer */
+ struct lapd_history *tx_hist; /*!< \brief tx history structure array */
+ uint8_t range_hist; /*!< \brief range of history buffer 2..2^n */
+ struct msgb *rcv_buffer; /*!< \brief buffer to assemble the received message */
+ struct msgb *cont_res; /*!< \brief buffer to store content resolution data on network side, to detect multiple phones on same channel */
+};
+
+void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
+ int maxf);
+void lapd_dl_exit(struct lapd_datalink *dl);
+void lapd_dl_reset(struct lapd_datalink *dl);
+int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode);
+int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx);
+int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
+
+#endif /* _OSMOCOM_LAPD_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapdm.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapdm.h
index b71feef..52e8fc5 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapdm.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/lapdm.h
@@ -1,11 +1,7 @@
#ifndef _OSMOCOM_LAPDM_H
#define _OSMOCOM_LAPDM_H
-#include <stdint.h>
-
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/prim.h>
+#include <osmocom/gsm/lapd_core.h>
/*! \defgroup lapdm LAPDm implementation according to GSM TS 04.06
* @{
@@ -15,7 +11,7 @@
/* primitive related sutff */
-/*! \brief LAPDm related primitives */
+/*! \brief LAPDm related primitives (L1<->L2 SAP) */
enum osmo_ph_prim {
PRIM_PH_DATA, /*!< \brief PH-DATA */
PRIM_PH_RACH, /*!< \brief PH-RANDOM_ACCESS */
@@ -68,52 +64,22 @@ enum lapdm_mode {
LAPDM_MODE_BTS, /*!< \brief behave like a BTS (network) */
};
-/*! \brief LAPDm state */
-enum lapdm_state {
- LAPDm_STATE_NULL = 0,
- LAPDm_STATE_IDLE,
- LAPDm_STATE_SABM_SENT,
- LAPDm_STATE_MF_EST,
- LAPDm_STATE_TIMER_RECOV,
- LAPDm_STATE_DISC_SENT,
-};
-
struct lapdm_entity;
/*! \brief LAPDm message context */
struct lapdm_msg_ctx {
struct lapdm_datalink *dl;
int lapdm_fmt;
- uint8_t n201;
uint8_t chan_nr;
uint8_t link_id;
- uint8_t addr;
- uint8_t ctrl;
- uint8_t ta_ind;
- uint8_t tx_power_ind;
+ uint8_t ta_ind; /* TA indicated by network */
+ uint8_t tx_power_ind; /* MS power indicated by network */
};
/*! \brief LAPDm datalink like TS 04.06 / Section 3.5.2 */
struct lapdm_datalink {
- uint8_t V_send; /*!< \brief seq nr of next I frame to be transmitted */
- uint8_t V_ack; /*!< \brief last frame ACKed by peer */
- uint8_t N_send; /*!< \brief ? set to V_send at Tx time*/
- uint8_t V_recv; /*!< \brief seq nr of next I frame expected to be received */
- uint8_t N_recv; /*!< \brief expected send seq nr of the next received I frame */
- uint32_t state; /*!< \brief LAPDm state (\ref lapdm_state) */
- int seq_err_cond; /*!< \brief condition of sequence error */
- uint8_t own_busy; /*!< \brief receiver busy on our side */
- uint8_t peer_busy; /*!< \brief receiver busy on remote side */
- struct osmo_timer_list t200; /*!< \brief T200 timer */
- uint8_t retrans_ctr; /*!< \brief re-transmission counter */
- struct llist_head send_queue; /*!< \brief frames from L3 */
- struct msgb *send_buffer; /*!< \brief current frame transmitting */
- int send_out; /*!< \brief how much was sent from send_buffer */
- uint8_t tx_hist[8][200]; /*!< \brief tx history buffer */
- int tx_length[8]; /*!< \brief length in history buffer */
- struct llist_head tx_queue; /*!< \brief frames to L1 */
+ struct lapd_datalink dl; /* \brief common LAPD */
struct lapdm_msg_ctx mctx; /*!< \brief context of established connection */
- struct msgb *rcv_buffer; /*!< \brief buffer to assemble the received message */
struct lapdm_entity *entity; /*!< \brief LAPDm entity we are part of */
};
@@ -127,11 +93,6 @@ enum lapdm_dl_sapi {
typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx);
-struct lapdm_cr_ent {
- uint8_t cmd;
- uint8_t resp;
-};
-
#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
#define LAPDM_ENT_F_POLLING_ONLY 0x0002
@@ -144,12 +105,6 @@ struct lapdm_entity {
enum lapdm_mode mode; /*!< \brief are we in BTS mode or MS mode */
unsigned int flags;
- struct {
- /*! \brief filled-in once we set the lapdm_mode above */
- struct lapdm_cr_ent loc2rem;
- struct lapdm_cr_ent rem2loc;
- } cr;
-
void *l1_ctx; /*!< \brief context for layer1 instance */
void *l3_ctx; /*!< \brief context for layer3 instance */
@@ -158,6 +113,9 @@ struct lapdm_entity {
/*! \brief pointer to \ref lapdm_channel of which we're part */
struct lapdm_channel *lapdm_ch;
+
+ uint8_t ta; /* TA used and indicated to network */
+ uint8_t tx_power; /* MS power used and indicated to network */
};
/*! \brief the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
@@ -172,7 +130,7 @@ const char *get_rsl_name(int value);
extern const char *lapdm_state_names[];
/* initialize a LAPDm entity */
-void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode);
+void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200);
void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode);
/* deinitialize a LAPDm entity */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/Makefile.am b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/Makefile.am
index 7f6de63..6ed55e4 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/Makefile.am
@@ -1,6 +1,6 @@
osmogsm_proto_HEADERS = gsm_03_41.h \
gsm_04_08.h gsm_04_11.h gsm_04_12.h gsm_04_80.h \
- gsm_08_08.h gsm_08_58.h \
+ gsm_08_08.h gsm_08_58.h gsm_44_318.h \
gsm_12_21.h ipaccess.h
osmogsm_protodir = $(includedir)/osmocom/gsm/protocol
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_08.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_08.h
index 39470e7..5057ada 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_08.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_08.h
@@ -213,15 +213,15 @@ struct gsm48_chan_desc {
tsc:3;
uint8_t hsn:6,
maio_low:2;
- } h1;
+ } __attribute__ ((packed)) h1;
struct {
uint8_t arfcn_high:2,
spare:2,
h:1,
tsc:3;
uint8_t arfcn_low;
- } h0;
- };
+ } __attribute__ ((packed)) h0;
+ } __attribute__ ((packed));
} __attribute__ ((packed));
/* Chapter 10.5.2.20 */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_11.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_11.h
index c6a2b19..f37152f 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_11.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_04_11.h
@@ -5,7 +5,7 @@
/* GSM TS 04.11 definitions */
-/* Chapter 5.2.3: SMC-CS states at the network side */
+/* Chapter 5.2.3: SMC-CS states at the user/network side */
enum gsm411_cp_state {
GSM411_CPS_IDLE = 0,
GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */
@@ -13,11 +13,12 @@ enum gsm411_cp_state {
GSM411_CPS_MM_ESTABLISHED = 3,
};
-/* Chapter 6.2.2: SMR states at the network side */
+/* Chapter 6.2.2: SMR states at the user/network side */
enum gsm411_rp_state {
GSM411_RPS_IDLE = 0,
GSM411_RPS_WAIT_FOR_RP_ACK = 1,
GSM411_RPS_WAIT_TO_TX_RP_ACK = 3,
+ GSM411_RPS_WAIT_FOR_RETRANS_T = 4,
};
/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
@@ -95,7 +96,8 @@ enum gsm411_rp_cause {
#define GSM411_TMR_TRAM 30, 0 /* 25 < x < 35 seconds */
#define GSM411_TMR_TR2M 15, 0 /* 12 < x < 20 seconds */
-#define GSM411_TMR_TC1A 30, 0
+#define GSM411_TMR_TC1A 30, 0 /* TR1M - 10 */
+#define GSM411_TMR_TC1A_SEC 30 /* TR1M - 10 */
/* Chapter 8.2.1 */
struct gsm411_rp_hdr {
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_44_318.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_44_318.h
new file mode 100644
index 0000000..31c0ea7
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/protocol/gsm_44_318.h
@@ -0,0 +1,153 @@
+#ifndef PROTO_GSM_44_318_H
+#define PROTO_GSM_44_318_H
+
+#include <stdint.h>
+
+/* Definitions according to 3GPP TS 44.318 6.8.0 Release 6 */
+
+/* Table 11.1.1.4.1: Message types for URR */
+
+enum gan_msg_type {
+ GA_MT_RC_DISCOVERY_REQUEST = 0x01,
+ GA_MT_RC_DISCOVERY_ACCEPT = 0x02,
+ GA_MT_RC_DISCOVERY_REJECT = 0x03,
+
+ GA_MT_RC_REGISTER_REQUEST = 0x10,
+ GA_MT_RC_REGISTER_ACCEPT = 0x11,
+ GA_MT_RC_REGISTER_REDIRECT = 0x12,
+ GA_MT_RC_REGISTER_REJECT = 0x13,
+ GA_MT_RC_DEREGISTER = 0x14,
+ GA_MT_RC_REGISTER_UPDATE_UL = 0x15,
+ GA_MT_RC_REGISTER_UPDATE_DL = 0x16,
+ GA_MT_RC_CELL_BCAST_INFO = 0x17,
+
+ GA_MT_CSR_CIPH_MODE_CMD = 0x20,
+ GA_MT_CSR_CIPH_MODE_COMPL = 0x21,
+
+ GA_MT_CSR_ACT_CHAN = 0x30,
+ GA_MT_CSR_ACT_CHAN_ACK = 0x31,
+ GA_MT_CSR_ACT_CHAN_COMPL = 0x32,
+ GA_MT_CSR_ACT_CHAN_FAIL = 0x33,
+ GA_MT_CSR_CHAN_MODE_MOD = 0x34,
+ GA_MT_CSR_CHAN_MODE_MOD_ACK = 0x35,
+
+ GA_MT_CSR_RELEASE = 0x40,
+ GA_MT_CSR_RELEASE_COMPL = 0x41,
+ GA_MT_CSR_CLEAR_REQ = 0x42,
+
+ GA_MT_CSR_HO_ACCESS = 0x50,
+ GA_MT_CSR_HO_COMPL = 0x51,
+ GA_MT_CSR_UL_QUAL_IND = 0x52,
+ GA_MT_CSR_HO_INFO = 0x53,
+ GA_MT_CSR_HO_CMD = 0x54,
+ GA_MT_CSR_HO_FAIL = 0x55,
+
+ GA_MT_CSR_PAGING_REQ = 0x60,
+ GA_MT_CSR_PAGING_RESP = 0x61,
+
+ GA_MT_CSR_UL_DIRECT_XFER = 0x70,
+ GA_MT_CSR_DL_DIRECT_XFER = 0x72,
+ GA_MT_CSR_STATUS = 0x73,
+ GA_MT_RC_KEEPALIVE = 0x74,
+ GA_MT_CSR_CM_ENQ = 0x75,
+ GA_MT_CSR_CM_CHANGE = 0x76,
+
+ GA_MT_CSR_REQUEST = 0x80,
+ GA_MT_CSR_REQUEST_ACCEPT = 0x81,
+ GA_MT_CSR_REQUEST_REJECT = 0x82,
+};
+
+/* All tables in 10.1.x and 10.2.x / Table 11.2.1 */
+enum gan_iei {
+ GA_IE_MI = 1,
+ GA_IE_GAN_RELEASE_IND = 2,
+ GA_IE_RADIO_IE = 3,
+ GA_IE_GERAN_CELL_ID = 4,
+ GA_IE_LAC = 5,
+ GA_IE_GERAN_COV_IND = 6,
+ GA_IE_GAN_CM = 7,
+ GA_IE_GEO_LOC = 8,
+ GA_IE_DEF_SEGW_IP = 9,
+ GA_IE_DEF_SEGW_FQDN = 10,
+ GA_IE_REDIR_CTR = 11,
+ GA_IE_DISCOV_REJ_CAUSE = 12,
+ GA_IE_GANC_CELL_DESC = 13,
+ GA_IE_GANC_CTRL_CH_DESC = 14,
+ GA_IE_GERAN_CELL_ID_LIST= 15,
+ GA_IE_TU3907_TIMER = 16,
+ GA_IE_RR_STATE = 17,
+ GA_IE_RAI = 18,
+ GA_IE_GAN_BAND = 19,
+ GA_IE_GARC_GACSR_STATE = 20,
+ GA_IE_REG_REJ_CAUSE = 21,
+ GA_IE_TU3906_TIMER = 22,
+ GA_IE_TU3910_TIMER = 23,
+ GA_IE_TU3902_TIMER = 24,
+ GA_IE_L3_MSG = 26,
+ GA_IE_CHAN_MODE = 27,
+ GA_IE_MS_CLASSMARK2 = 28,
+ GA_IE_RR_CAUSE = 29,
+ GA_EI_CIPH_MODE_SET = 30,
+ GA_IE_GPRS_RESUMPTION = 31,
+ GA_IE_HO_FROM_GAN_CMD = 32,
+ GA_IE_UL_QUAL_IND = 33,
+ GA_IE_TLLI = 34,
+ GA_IE_PFI = 35,
+ GA_IE_SUSP_CAUSE = 36,
+ GA_IE_TU3820_TIMER = 37,
+ GA_IE_REQD_QOS = 38,
+ GA_IE_P_DEACT_CAUSE = 39
+ GA_IE_REQD_UL_RATE = 40,
+ GA_IE_RAC = 41,
+ GA_IE_AP_LOCATION = 42,
+ GA_IE_TU4001_TIMER = 43,
+ GA_IE_LOC_STATUS = 44,
+ GA_IE_CIPH_RESP = 45,
+ GA_IE_CIPH_RAND = 46,
+ GA_IE_CIPH_MAC = 47,
+ GA_IE_CKSN = 48,
+ GA_IE_SAPI_ID = 49,
+ GA_IE_EST_CAUSE = 50,
+ GA_IE_CHAN_NEEDED = 51,
+ GA_IE_PDU_IN_ERROR = 52,
+ GA_IE_SAMPLE_SIZE = 53,
+ GA_IE_PAYLOAD_TYPE = 54,
+ GA_IE_MULTIRATE_CONF = 55,
+ GA_IE_MS_CLASSMARK3 = 56,
+ GA_IE_LLC_PDU = 57,
+ GA_IE_LOC_BLACKL_IND = 58,
+ GA_IE_RESET_IND = 59,
+ GA_IE_TU4003_TIMER = 60,
+ GA_IE_AP_SERV_NAME = 61,
+ GA_IE_SERV_ZONE_INFO = 62,
+ GA_IE_RTP_RED_CONF = 63,
+ GA_IE_UTRAN_CLASSMARK = 64,
+ GA_IE_CM_ENQ_MASK = 65,
+ GA_IE_UTRAN_CELLID_LIST = 66,
+ GA_IE_SERV_GANC_TBL_IND = 67,
+ GA_IE_AP_REG_IND = 68,
+ GA_IE_GAN_PLMN_LIST = 69,
+ GA_IE_REQD_GAN_SERV = 71,
+ GA_IE_BCAST_CONTAINER = 72,
+ GA_IE_3G_CELL_ID = 73,
+ GA_IE_MS_RADIO_ID = 96,
+ GA_IE_DEF_GANC_IP = 97,
+ GA_IE_DEF_GANC_FQDN = 98,
+ GA_IE_GPRS_IP_ADDR = 99,
+ GA_IE_GPRS_UDP_PORT = 100
+ GA_IE_GANC_TCP_PORT = 103,
+ GA_IE_RTP_UDP_PORT = 104,
+ GA_IE_RTCP_UDP_PORT = 105,
+ GA_IE_GERAN_RCV_SIGL_LIST = 106,
+ GA_IE_UTRAN_RCV_SIGL_LIST = 107,
+};
+
+/* 11.1.1 GA-RC and GA-CSR Message header IE */
+struct gan_rc_csr_hdr {
+ uint16_t len;
+ uint8_t pdisc:4,
+ skip_ind:4;
+ uint8_t msg_type;
+} __attribute__((packed));
+
+#endif /* PROTO_GSM_44_318_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/sysinfo.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/sysinfo.h
index b808d6f..06feb1d 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/sysinfo.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/sysinfo.h
@@ -37,7 +37,7 @@ typedef uint8_t sysinfo_buf_t[GSM_MACBLOCK_LEN];
extern const struct value_string osmo_sitype_strs[_MAX_SYSINFO_TYPE];
-uint8_t gsm_sitype2rsl(enum osmo_sysinfo_type si_type);
+uint8_t osmo_sitype2rsl(enum osmo_sysinfo_type si_type);
enum osmo_sysinfo_type osmo_rsl2sitype(uint8_t rsl_si);
#endif /* _OSMO_GSM_SYSINFO_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/tlv.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/tlv.h
index 7b41d2d..d2936d6 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/tlv.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/gsm/tlv.h
@@ -178,28 +178,32 @@ static inline uint8_t *tv16_put(uint8_t *buf, uint8_t tag,
return buf;
}
-/*! \brief put (append) a LV field to a \ref msgb */
+/*! \brief put (append) a LV field to a \ref msgb
+ * \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_lv_put(struct msgb *msg, uint8_t len, const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
return lv_put(buf, len, val);
}
-/*! \brief put (append) a TLV field to a \ref msgb */
+/*! \brief put (append) a TLV field to a \ref msgb
+ * \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_tlv_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
return tlv_put(buf, tag, len, val);
}
-/*! \brief put (append) a TV field to a \ref msgb */
+/*! \brief put (append) a TV field to a \ref msgb
+ * \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_tv_put(struct msgb *msg, uint8_t tag, uint8_t val)
{
uint8_t *buf = msgb_put(msg, 2);
return tv_put(buf, tag, val);
}
-/*! \brief put (append) a TVfixed field to a \ref msgb */
+/*! \brief put (append) a TVfixed field to a \ref msgb
+ * \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_tv_fixed_put(struct msgb *msg, uint8_t tag,
unsigned int len, const uint8_t *val)
{
@@ -207,47 +211,57 @@ static inline uint8_t *msgb_tv_fixed_put(struct msgb *msg, uint8_t tag,
return tv_fixed_put(buf, tag, len, val);
}
-/*! \brief put (append) a V field to a \ref msgb */
+/*! \brief put (append) a V field to a \ref msgb
+ * \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_v_put(struct msgb *msg, uint8_t val)
{
uint8_t *buf = msgb_put(msg, 1);
return v_put(buf, val);
}
-/*! \brief put (append) a TV16 field to a \ref msgb */
+/*! \brief put (append) a TV16 field to a \ref msgb
+ * \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_tv16_put(struct msgb *msg, uint8_t tag, uint16_t val)
{
uint8_t *buf = msgb_put(msg, 3);
return tv16_put(buf, tag, val);
}
-/*! \brief push (prepend) a TLV field to a \ref msgb */
+/*! \brief push (prepend) a TLV field to a \ref msgb
+ * \returns pointer to first byte of newly-pushed information */
static inline uint8_t *msgb_tlv_push(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val)
{
uint8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
- return tlv_put(buf, tag, len, val);
+ tlv_put(buf, tag, len, val);
+ return buf;
}
-/*! \brief push (prepend) a TV field to a \ref msgb */
+/*! \brief push (prepend) a TV field to a \ref msgb
+ * \returns pointer to first byte of newly-pushed information */
static inline uint8_t *msgb_tv_push(struct msgb *msg, uint8_t tag, uint8_t val)
{
uint8_t *buf = msgb_push(msg, 2);
- return tv_put(buf, tag, val);
+ tv_put(buf, tag, val);
+ return buf;
}
-/*! \brief push (prepend) a TV16 field to a \ref msgb */
+/*! \brief push (prepend) a TV16 field to a \ref msgb
+ * \returns pointer to first byte of newly-pushed information */
static inline uint8_t *msgb_tv16_push(struct msgb *msg, uint8_t tag, uint16_t val)
{
uint8_t *buf = msgb_push(msg, 3);
- return tv16_put(buf, tag, val);
+ tv16_put(buf, tag, val);
+ return buf;
}
-/*! \brief push (prepend) a TvLV field to a \ref msgb */
+/*! \brief push (prepend) a TvLV field to a \ref msgb
+ * \returns pointer to first byte of newly-pushed information */
static inline uint8_t *msgb_tvlv_push(struct msgb *msg, uint8_t tag, uint16_t len,
const uint8_t *val)
{
uint8_t *buf = msgb_push(msg, TVLV_GROSS_LEN(len));
- return tvlv_put(buf, tag, len, val);
+ tvlv_put(buf, tag, len, val);
+ return buf;
}
/* TLV parsing */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/telnet_interface.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/telnet_interface.h
index 9a7c9e5..2de4f19 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/telnet_interface.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/telnet_interface.h
@@ -48,6 +48,8 @@ struct telnet_connection {
int telnet_init(void *tall_ctx, void *priv, int port);
+void telnet_exit(void);
+
/*! }@ */
#endif /* TELNET_INTERFACE_H */
diff --git a/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/vty.h b/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/vty.h
index d1f6f44..83506c5 100644
--- a/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/vty.h
+++ b/Src/osmolib/src/shared/libosmocore/include/osmocom/vty/vty.h
@@ -176,9 +176,13 @@ int vty_shell_serv (struct vty *);
void vty_hello (struct vty *);
void *vty_current_index(struct vty *);
int vty_current_node(struct vty *vty);
+enum node_type vty_go_parent(struct vty *vty);
extern void *tall_vty_ctx;
+extern struct cmd_element cfg_description_cmd;
+extern struct cmd_element cfg_no_description_cmd;
+
/*! }@ */
#endif
diff --git a/Src/osmolib/src/shared/libosmocore/src/Makefile.am b/Src/osmolib/src/shared/libosmocore/src/Makefile.am
index 739095c..079d0b4 100644
--- a/Src/osmolib/src/shared/libosmocore/src/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/src/Makefile.am
@@ -2,9 +2,9 @@ SUBDIRS=. vty codec gsm
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
-LIBVERSION=2:0:0
+LIBVERSION=4:0:0
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
+INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)/include
AM_CFLAGS = -fPIC -Wall
lib_LTLIBRARIES = libosmocore.la
@@ -14,17 +14,20 @@ libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \
write_queue.c utils.c socket.c \
logging.c logging_syslog.c rate_ctr.c \
gsmtap_util.c crc16.c panic.c backtrace.c \
- conv.c application.c
+ conv.c application.c rbtree.c \
+ crc8gen.c crc16gen.c crc32gen.c crc64gen.c
if ENABLE_PLUGIN
libosmocore_la_SOURCES += plugin.c
-libosmocore_la_LDFLAGS = -version-info $(LIBVERSION) -ldl
+libosmocore_la_LDFLAGS = -version-info $(LIBVERSION) $(LIBRARY_DL)
else
libosmocore_la_LDFLAGS = -version-info $(LIBVERSION)
endif
if ENABLE_TALLOC
libosmocore_la_SOURCES += talloc.c
+else
+libosmocore_la_LIBADD = -ltalloc
endif
if ENABLE_MSGFILE
@@ -34,3 +37,7 @@ endif
if ENABLE_SERIAL
libosmocore_la_SOURCES += serial.c
endif
+
+crc%gen.c: crcXXgen.c.tpl
+ @echo " SED $< -> $@"
+ @sed -e's/XX/$*/g' $< > $@
diff --git a/Src/osmolib/src/shared/libosmocore/src/backtrace.c b/Src/osmolib/src/shared/libosmocore/src/backtrace.c
index 189a3ce..023671c 100644
--- a/Src/osmolib/src/shared/libosmocore/src/backtrace.c
+++ b/Src/osmolib/src/shared/libosmocore/src/backtrace.c
@@ -57,4 +57,8 @@ void osmo_generate_backtrace(void)
free(strings);
}
+#else
+void osmo_generate_backtrace(void)
+{
+}
#endif
diff --git a/Src/osmolib/src/shared/libosmocore/src/conv.c b/Src/osmolib/src/shared/libosmocore/src/conv.c
index f47d75c..ac39e29 100644
--- a/Src/osmolib/src/shared/libosmocore/src/conv.c
+++ b/Src/osmolib/src/shared/libosmocore/src/conv.c
@@ -29,8 +29,10 @@
/*! \file conv.c
* \file Osmocom convolutional encoder and decoder
*/
-
+#include "config.h"
+#ifdef HAVE_ALLOCA_H
#include <alloca.h>
+#endif
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -40,6 +42,40 @@
/* ------------------------------------------------------------------------ */
+/* Common */
+/* ------------------------------------------------------------------------ */
+
+int
+osmo_conv_get_input_length(const struct osmo_conv_code *code, int len)
+{
+ return len <= 0 ? code->len : len;
+}
+
+int
+osmo_conv_get_output_length(const struct osmo_conv_code *code, int len)
+{
+ int pbits, in_len, out_len;
+
+ /* Input length */
+ in_len = osmo_conv_get_input_length(code, len);
+
+ /* Output length */
+ out_len = in_len * code->N;
+
+ if (code->term == CONV_TERM_FLUSH)
+ out_len += code->N * (code->K - 1);
+
+ /* Count punctured bits */
+ if (code->puncture) {
+ for (pbits=0; code->puncture[pbits] >= 0; pbits++);
+ out_len -= pbits;
+ }
+
+ return out_len;
+}
+
+
+/* ------------------------------------------------------------------------ */
/* Encoding */
/* ------------------------------------------------------------------------ */
@@ -55,6 +91,19 @@ osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
encoder->code = code;
}
+void
+osmo_conv_encode_load_state(struct osmo_conv_encoder *encoder,
+ const ubit_t *input)
+{
+ int i;
+ uint8_t state = 0;
+
+ for (i=0; i<(encoder->code->K-1); i++)
+ state = (state << 1) | input[i];
+
+ encoder->state = state;
+}
+
static inline int
_conv_encode_do_output(struct osmo_conv_encoder *encoder,
uint8_t out, ubit_t *output)
@@ -115,8 +164,8 @@ osmo_conv_encode_raw(struct osmo_conv_encoder *encoder,
}
int
-osmo_conv_encode_finish(struct osmo_conv_encoder *encoder,
- ubit_t *output)
+osmo_conv_encode_flush(struct osmo_conv_encoder *encoder,
+ ubit_t *output)
{
const struct osmo_conv_code *code = encoder->code;
uint8_t state;
@@ -154,10 +203,11 @@ osmo_conv_encode_finish(struct osmo_conv_encoder *encoder,
* \param[in] code description of convolutional code to be used
* \param[in] input array of unpacked bits (uncoded)
* \param[out] output array of unpacked bits (encoded)
+ * \return Number of produced output bits
*
* This is an all-in-one function, taking care of
- * \ref osmo_conv_init, \ref osmo_conv_encode_raw and
- * \ref osmo_conv_encode_finish.
+ * \ref osmo_conv_init, \ref osmo_conv_encode_load_state,
+ * \ref osmo_conv_encode_raw and \ref osmo_conv_encode_flush as needed.
*/
int
osmo_conv_encode(const struct osmo_conv_code *code,
@@ -167,8 +217,16 @@ osmo_conv_encode(const struct osmo_conv_code *code,
int l;
osmo_conv_encode_init(&encoder, code);
- l = osmo_conv_encode_raw(&encoder, input, output, code->len);
- l += osmo_conv_encode_finish(&encoder, &output[l]);
+
+ if (code->term == CONV_TERM_TAIL_BITING) {
+ int eidx = code->len - code->K + 1;
+ osmo_conv_encode_load_state(&encoder, &input[eidx]);
+ }
+
+ l = osmo_conv_encode_raw(&encoder, input, output, code->len);
+
+ if (code->term == CONV_TERM_FLUSH)
+ l += osmo_conv_encode_flush(&encoder, &output[l]);
return l;
}
@@ -182,7 +240,7 @@ osmo_conv_encode(const struct osmo_conv_code *code,
void
osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
- const struct osmo_conv_code *code, int len)
+ const struct osmo_conv_code *code, int len, int start_state)
{
int n_states;
@@ -205,23 +263,48 @@ osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
decoder->state_history = malloc(sizeof(uint8_t) * n_states * (len + decoder->code->K - 1));
/* Classic reset */
- osmo_conv_decode_reset(decoder);
+ osmo_conv_decode_reset(decoder, start_state);
+}
+
+void
+osmo_conv_decode_reset(struct osmo_conv_decoder *decoder, int start_state)
+{
+ int i;
+
+ /* Reset indexes */
+ decoder->o_idx = 0;
+ decoder->p_idx = 0;
+
+ /* Initial error */
+ if (start_state < 0) {
+ /* All states possible */
+ memset(decoder->ae, 0x00, sizeof(unsigned int) * decoder->n_states);
+ } else {
+ /* Fixed start state */
+ for (i=0; i<decoder->n_states; i++) {
+ decoder->ae[i] = (i == start_state) ? 0 : MAX_AE;
+ }
+ }
}
void
-osmo_conv_decode_reset(struct osmo_conv_decoder *decoder)
+osmo_conv_decode_rewind(struct osmo_conv_decoder *decoder)
{
int i;
+ unsigned int min_ae = MAX_AE;
/* Reset indexes */
decoder->o_idx = 0;
decoder->p_idx = 0;
- /* Initial error (only state 0 is valid) */
- decoder->ae[0] = 0;
- for (i=1; i<decoder->n_states; i++) {
- decoder->ae[i] = MAX_AE;
+ /* Initial error normalize (remove constant) */
+ for (i=0; i<decoder->n_states; i++) {
+ if (decoder->ae[i] < min_ae)
+ min_ae = decoder->ae[i];
}
+
+ for (i=0; i<decoder->n_states; i++)
+ decoder->ae[i] -= min_ae;
}
void
@@ -307,9 +390,12 @@ osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
m = 1 << (code->N - 1); /* mask for 'out' bit selection */
for (j=0; j<code->N; j++) {
- ov = (out & m) ? -127 : 127; /* sbit_t value for it */
- e = ((int)in_sym[j]) - ov; /* raw error for this bit */
- nae += (e * e) >> 9; /* acc the squared/scaled value */
+ int is = (int)in_sym[j];
+ if (is) {
+ ov = (out & m) ? -127 : 127; /* sbit_t value for it */
+ e = is - ov; /* raw error for this bit */
+ nae += (e * e) >> 9; /* acc the squared/scaled value */
+ }
m >>= 1; /* next mask bit */
}
@@ -333,8 +419,8 @@ osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
}
int
-osmo_conv_decode_finish(struct osmo_conv_decoder *decoder,
- const sbit_t *input)
+osmo_conv_decode_flush(struct osmo_conv_decoder *decoder,
+ const sbit_t *input)
{
const struct osmo_conv_code *code = decoder->code;
@@ -439,7 +525,7 @@ osmo_conv_decode_finish(struct osmo_conv_decoder *decoder,
int
osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
- ubit_t *output, int has_finish)
+ ubit_t *output, int has_flush, int end_state)
{
const struct osmo_conv_code *code = decoder->code;
@@ -449,20 +535,26 @@ osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
uint8_t *sh_ptr;
- /* Find state with least error */
- min_ae = MAX_AE;
- min_state = 0xff;
+ /* End state ? */
+ if (end_state < 0) {
+ /* Find state with least error */
+ min_ae = MAX_AE;
+ min_state = 0xff;
- for (s=0; s<decoder->n_states; s++)
- {
- if (decoder->ae[s] < min_ae) {
- min_ae = decoder->ae[s];
- min_state = s;
+ for (s=0; s<decoder->n_states; s++)
+ {
+ if (decoder->ae[s] < min_ae) {
+ min_ae = decoder->ae[s];
+ min_state = s;
+ }
}
- }
- if (min_state == 0xff)
- return -1;
+ if (min_state == 0xff)
+ return -1;
+ } else {
+ min_state = (uint8_t) end_state;
+ min_ae = decoder->ae[end_state];
+ }
/* Traceback */
cur_state = min_state;
@@ -472,7 +564,7 @@ osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
sh_ptr = &decoder->state_history[decoder->n_states * (n-1)];
/* No output for the K-1 termination input bits */
- if (has_finish) {
+ if (has_flush) {
for (i=0; i<code->K-1; i++) {
cur_state = sh_ptr[cur_state];
sh_ptr -= decoder->n_states;
@@ -504,7 +596,7 @@ osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
*
* This is an all-in-one function, taking care of
* \ref osmo_conv_decode_init, \ref osmo_conv_decode_scan,
- * \ref osmo_conv_decode_finish, \ref osmo_conv_decode_get_output and
+ * \ref osmo_conv_decode_flush, \ref osmo_conv_decode_get_output and
* \ref osmo_conv_decode_deinit.
*/
int
@@ -514,12 +606,22 @@ osmo_conv_decode(const struct osmo_conv_code *code,
struct osmo_conv_decoder decoder;
int rv, l;
- osmo_conv_decode_init(&decoder, code, 0);
+ osmo_conv_decode_init(&decoder, code, 0, 0);
+
+ if (code->term == CONV_TERM_TAIL_BITING) {
+ osmo_conv_decode_scan(&decoder, input, code->len);
+ osmo_conv_decode_rewind(&decoder);
+ }
l = osmo_conv_decode_scan(&decoder, input, code->len);
- l = osmo_conv_decode_finish(&decoder, &input[l]);
- rv = osmo_conv_decode_get_output(&decoder, output, 1);
+ if (code->term == CONV_TERM_FLUSH)
+ l = osmo_conv_decode_flush(&decoder, &input[l]);
+
+ rv = osmo_conv_decode_get_output(&decoder, output,
+ code->term == CONV_TERM_FLUSH, /* has_flush */
+ code->term == CONV_TERM_FLUSH ? 0 : -1 /* end_state */
+ );
osmo_conv_decode_deinit(&decoder);
diff --git a/Src/osmolib/src/shared/libosmocore/src/crcXXgen.c.tpl b/Src/osmolib/src/shared/libosmocore/src/crcXXgen.c.tpl
new file mode 100644
index 0000000..5d70753
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/crcXXgen.c.tpl
@@ -0,0 +1,120 @@
+/*
+ * crcXXgen.c
+ *
+ * Generic CRC routines (for max XX bits poly)
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crcXXgen.c
+ * \file Osmocom generic CRC routines (for max XX bits poly)
+ */
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/crcXXgen.h>
+
+
+/*! \brief Compute the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \returns The CRC value
+ */
+uintXX_t
+osmo_crcXXgen_compute_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len)
+{
+ const uintXX_t poly = code->poly;
+ uintXX_t crc = code->init;
+ int i, n = code->bits-1;
+
+ for (i=0; i<len; i++) {
+ uintXX_t bit = in[i] & 1;
+ crc ^= (bit << n);
+ if (crc & (1 << n)) {
+ crc <<= 1;
+ crc ^= poly;
+ } else {
+ crc <<= 1;
+ }
+ crc &= (1ULL << code->bits) - 1;
+ }
+
+ crc ^= code->remainder;
+
+ return crc;
+}
+
+
+/*! \brief Checks the CRC value of a given array of hard-bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits with the alleged CRC
+ * \returns 0 if CRC matches. 1 in case of error.
+ *
+ * The crc_bits array must have a length of code->len
+ */
+int
+osmo_crcXXgen_check_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits)
+{
+ uintXX_t crc;
+ int i;
+
+ crc = osmo_crcXXgen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
+ return 1;
+
+ return 0;
+}
+
+
+/*! \brief Computes and writes the CRC value of a given array of bits
+ * \param[in] code The CRC code description to apply
+ * \param[in] in Array of hard bits
+ * \param[in] len Length of the array of hard bits
+ * \param[in] crc_bits Array of hard bits to write the computed CRC to
+ *
+ * The crc_bits array must have a length of code->len
+ */
+void
+osmo_crcXXgen_set_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits)
+{
+ uintXX_t crc;
+ int i;
+
+ crc = osmo_crcXXgen_compute_bits(code, in, len);
+
+ for (i=0; i<code->bits; i++)
+ crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
+}
+
+/*! }@ */
+
+/* vim: set syntax=c: */
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/Makefile.am b/Src/osmolib/src/shared/libosmocore/src/gsm/Makefile.am
index f5e4676..46d40a1 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsm/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/Makefile.am
@@ -1,15 +1,25 @@
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
-LIBVERSION=1:0:0
+LIBVERSION=2:0:1
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS = -fPIC -Wall
+# FIXME: this should eventually go into a milenage/Makefile.am
+noinst_HEADERS = milenage/aes.h milenage/aes_i.h milenage/aes_wrap.h \
+ milenage/common.h milenage/crypto.h milenage/includes.h \
+ milenage/milenage.h
+
lib_LTLIBRARIES = libosmogsm.la
libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c gsm_utils.c \
rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \
gprs_cipher_core.c gsm0480.c abis_nm.c gsm0502.c \
- lapdm.c
+ gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \
+ lapd_core.c lapdm.c \
+ auth_core.c auth_comp128v1.c auth_milenage.c \
+ milenage/aes-encblock.c milenage/aes-internal.c \
+ milenage/aes-internal-enc.c milenage/milenage.c
+
libosmogsm_la_LDFLAGS = -version-info $(LIBVERSION)
libosmogsm_la_LIBADD = $(top_builddir)/src/libosmocore.la
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/a5.c b/Src/osmolib/src/shared/libosmocore/src/gsm/a5.c
index d3f2b2c..e330c75 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsm/a5.c
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/a5.c
@@ -26,12 +26,30 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+/*! \addtogroup a5
+ * @{
+ */
+
+/*! \file gsm/a5.c
+ * \brief Osmocom GSM A5 ciphering algorithm implementation
+ */
+
#include <string.h>
#include <osmocom/gsm/a5.h>
+/*! \brief Main method to generate a A5/x cipher stream
+ * \param[in] n Which A5/x method to use
+ * \param[in] key 8 byte array for the key (as received from the SIM)
+ * \param[in] fn Frame number
+ * \param[out] dl Pointer to array of ubits to return Downlink cipher stream
+ * \param[out] ul Pointer to array of ubits to return Uplink cipher stream
+ *
+ * Currently A5/[0-2] are supported.
+ * Either (or both) of dl/ul can be NULL if not needed.
+ */
void
-osmo_a5(int n, uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
+osmo_a5(int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
{
switch (n)
{
@@ -76,23 +94,38 @@ osmo_a5(int n, uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
#define A5_R3_TAPS 0x700080 /* x^23 + x^15 + x^2 + x + 1 */
#define A5_R4_TAPS 0x010800 /* x^17 + x^5 + 1 */
+/*! \brief Computes parity of a 32-bit word
+ * \param[in] x 32 bit word
+ * \return Parity bit (xor of all bits) as 0 or 1
+ */
static inline uint32_t
_a5_12_parity(uint32_t x)
{
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
- x ^= x >> 2;
- x ^= x >> 1;
- return x & 1;
+ x &= 0xf;
+ return (0x6996 >> x) & 1;
}
+/*! \brief Compute majority bit from 3 taps
+ * \param[in] v1 LFSR state ANDed with tap-bit
+ * \param[in] v2 LFSR state ANDed with tap-bit
+ * \param[in] v3 LFSR state ANDed with tap-bit
+ * \return The majority bit (0 or 1)
+ */
static inline uint32_t
_a5_12_majority(uint32_t v1, uint32_t v2, uint32_t v3)
{
return (!!v1 + !!v2 + !!v3) >= 2;
}
+/*! \brief Compute the next LFSR state
+ * \param[in] r Current state
+ * \param[in] mask LFSR mask
+ * \param[in] taps LFSR taps
+ * \return Next state
+ */
static inline uint32_t
_a5_12_clock(uint32_t r, uint32_t mask, uint32_t taps)
{
@@ -108,6 +141,10 @@ _a5_12_clock(uint32_t r, uint32_t mask, uint32_t taps)
#define A51_R2_CLKBIT 0x000400
#define A51_R3_CLKBIT 0x000400
+/*! \brief GSM A5/1 Clocking function
+ * \param[in] r Register state
+ * \param[in] force Non-zero value disable conditional clocking
+ */
static inline void
_a5_1_clock(uint32_t r[], int force)
{
@@ -129,6 +166,10 @@ _a5_1_clock(uint32_t r[], int force)
r[2] = _a5_12_clock(r[2], A5_R3_MASK, A5_R3_TAPS);
}
+/*! \brief GSM A5/1 Output function
+ * \param[in] r Register state
+ * \return The A5/1 output function bit
+ */
static inline uint8_t
_a5_1_get_output(uint32_t r[])
{
@@ -137,8 +178,16 @@ _a5_1_get_output(uint32_t r[])
(r[2] >> (A5_R3_LEN-1));
}
+/*! \brief Generate a GSM A5/1 cipher stream
+ * \param[in] key 8 byte array for the key (as received from the SIM)
+ * \param[in] fn Frame number
+ * \param[out] dl Pointer to array of ubits to return Downlink cipher stream
+ * \param[out] ul Pointer to array of ubits to return Uplink cipher stream
+ *
+ * Either (or both) of dl/ul can be NULL if not needed.
+ */
void
-osmo_a5_1(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
+osmo_a5_1(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
{
uint32_t r[3] = {0, 0, 0};
uint32_t fn_count;
@@ -200,6 +249,10 @@ osmo_a5_1(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
#define A52_R4_CLKBIT1 0x000008
#define A52_R4_CLKBIT2 0x000080
+/*! \brief GSM A5/2 Clocking function
+ * \param[in] r Register state
+ * \param[in] force Non-zero value disable conditional clocking
+ */
static inline void
_a5_2_clock(uint32_t r[], int force)
{
@@ -223,33 +276,39 @@ _a5_2_clock(uint32_t r[], int force)
r[3] = _a5_12_clock(r[3], A5_R4_MASK, A5_R4_TAPS);
}
+/*! \brief GSM A5/2 Output function
+ * \param[in] r Register state
+ * \return The A5/2 output function bit
+ */
static inline uint8_t
-_a5_2_get_output(uint32_t r[], uint8_t *db)
+_a5_2_get_output(uint32_t r[])
{
- uint8_t cb, tb;
-
- tb = (r[0] >> (A5_R1_LEN-1)) ^
- (r[1] >> (A5_R2_LEN-1)) ^
- (r[2] >> (A5_R3_LEN-1));
-
- cb = *db;
+ uint8_t b;
- *db = ( tb ^
- _a5_12_majority( r[0] & 0x08000, ~r[0] & 0x04000, r[0] & 0x1000) ^
- _a5_12_majority(~r[1] & 0x10000, r[1] & 0x02000, r[1] & 0x0200) ^
- _a5_12_majority( r[2] & 0x40000, r[2] & 0x10000, ~r[2] & 0x2000)
- );
+ b = (r[0] >> (A5_R1_LEN-1)) ^
+ (r[1] >> (A5_R2_LEN-1)) ^
+ (r[2] >> (A5_R3_LEN-1)) ^
+ _a5_12_majority( r[0] & 0x08000, ~r[0] & 0x04000, r[0] & 0x1000) ^
+ _a5_12_majority(~r[1] & 0x10000, r[1] & 0x02000, r[1] & 0x0200) ^
+ _a5_12_majority( r[2] & 0x40000, r[2] & 0x10000, ~r[2] & 0x2000);
- return cb;
+ return b;
}
+/*! \brief Generate a GSM A5/1 cipher stream
+ * \param[in] key 8 byte array for the key (as received from the SIM)
+ * \param[in] fn Frame number
+ * \param[out] dl Pointer to array of ubits to return Downlink cipher stream
+ * \param[out] ul Pointer to array of ubits to return Uplink cipher stream
+ *
+ * Either (or both) of dl/ul can be NULL if not needed.
+ */
void
-osmo_a5_2(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
+osmo_a5_2(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
{
uint32_t r[4] = {0, 0, 0, 0};
uint32_t fn_count;
uint32_t b;
- uint8_t db = 0, o;
int i;
/* Key load */
@@ -286,26 +345,23 @@ osmo_a5_2(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
r[3] |= 1 << 10;
/* Mix */
- for (i=0; i<100; i++)
+ for (i=0; i<99; i++)
{
_a5_2_clock(r, 0);
}
- _a5_2_get_output(r, &db);
-
-
/* Output */
for (i=0; i<114; i++) {
_a5_2_clock(r, 0);
- o = _a5_2_get_output(r, &db);
if (dl)
- dl[i] = o;
+ dl[i] = _a5_2_get_output(r);
}
for (i=0; i<114; i++) {
_a5_2_clock(r, 0);
- o = _a5_2_get_output(r, &db);
if (ul)
- ul[i] = o;
+ ul[i] = _a5_2_get_output(r);
}
}
+
+/*! }@ */
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/auth_comp128v1.c b/Src/osmolib/src/shared/libosmocore/src/gsm/auth_comp128v1.c
new file mode 100644
index 0000000..41aef71
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/auth_comp128v1.c
@@ -0,0 +1,47 @@
+
+/* GSM/GPRS/3G authentication core infrastructure */
+
+/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocom/crypt/auth.h>
+#include <osmocom/gsm/comp128.h>
+
+static int c128v1_gen_vec(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *_rand)
+{
+ comp128(aud->u.gsm.ki, _rand, vec->sres, vec->kc);
+ vec->auth_types = OSMO_AUTH_TYPE_GSM;
+
+ return 0;
+}
+
+static struct osmo_auth_impl c128v1_alg = {
+ .algo = OSMO_AUTH_ALG_COMP128v1,
+ .name = "COMP128v1 (libosmogsm built-in)",
+ .priority = 1000,
+ .gen_vec = &c128v1_gen_vec,
+};
+
+static __attribute__((constructor)) void on_dso_load_c128(void)
+{
+ osmo_auth_register(&c128v1_alg);
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/auth_core.c b/Src/osmolib/src/shared/libosmocore/src/gsm/auth_core.c
new file mode 100644
index 0000000..f790ff5
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/auth_core.c
@@ -0,0 +1,121 @@
+/* GSM/GPRS/3G authentication core infrastructure */
+
+/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/plugin.h>
+
+#include <osmocom/crypt/auth.h>
+
+static LLIST_HEAD(osmo_auths);
+
+static struct osmo_auth_impl *selected_auths[_OSMO_AUTH_ALG_NUM];
+
+/* register a cipher with the core */
+int osmo_auth_register(struct osmo_auth_impl *impl)
+{
+ if (impl->algo >= ARRAY_SIZE(selected_auths))
+ return -ERANGE;
+
+ llist_add_tail(&impl->list, &osmo_auths);
+
+ /* check if we want to select this implementation over others */
+ if (!selected_auths[impl->algo] ||
+ (selected_auths[impl->algo]->priority > impl->priority))
+ selected_auths[impl->algo] = impl;
+
+ return 0;
+}
+
+/* load all available GPRS cipher plugins */
+int osmo_auth_load(const char *path)
+{
+ /* load all plugins available from path */
+ return osmo_plugin_load_all(path);
+}
+
+int osmo_auth_supported(enum osmo_auth_algo algo)
+{
+ if (algo >= ARRAY_SIZE(selected_auths))
+ return -ERANGE;
+
+ if (selected_auths[algo])
+ return 1;
+
+ return 0;
+}
+
+int osmo_auth_gen_vec(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *_rand)
+{
+ struct osmo_auth_impl *impl = selected_auths[aud->algo];
+ int rc;
+
+ if (!impl)
+ return -ENOENT;
+
+ rc = impl->gen_vec(vec, aud, _rand);
+ if (rc < 0)
+ return rc;
+
+ memcpy(vec->rand, _rand, sizeof(vec->rand));
+
+ return 0;
+}
+
+int osmo_auth_gen_vec_auts(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *rand_auts, const uint8_t *auts,
+ const uint8_t *_rand)
+{
+ struct osmo_auth_impl *impl = selected_auths[aud->algo];
+
+ if (!impl || !impl->gen_vec_auts)
+ return -ENOENT;
+
+ return impl->gen_vec_auts(vec, aud, rand_auts, auts, _rand);
+}
+
+const struct value_string auth_alg_vals[] = {
+ { OSMO_AUTH_ALG_NONE, "None" },
+ { OSMO_AUTH_ALG_COMP128v1, "COMP128v1" },
+ { OSMO_AUTH_ALG_COMP128v2, "COMP128v2" },
+ { OSMO_AUTH_ALG_COMP128v3, "COMP128v3" },
+ { OSMO_AUTH_ALG_XOR, "XOR" },
+ { OSMO_AUTH_ALG_MILENAGE, "MILENAGE" },
+ { 0, NULL }
+};
+
+const char *osmo_auth_alg_name(enum osmo_auth_algo alg)
+{
+ return get_value_string(auth_alg_vals, alg);
+}
+
+enum osmo_auth_algo osmo_auth_alg_parse(const char *name)
+{
+ return get_string_value(auth_alg_vals, name);
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/auth_milenage.c b/Src/osmolib/src/shared/libosmocore/src/gsm/auth_milenage.c
new file mode 100644
index 0000000..2a9ba33
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/auth_milenage.c
@@ -0,0 +1,109 @@
+/* GSM/GPRS/3G authentication core infrastructure */
+
+/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocom/crypt/auth.h>
+#include "milenage/common.h"
+#include "milenage/milenage.h"
+
+static void sqn_u64_to_48bit(uint8_t *sqn, const uint64_t sqn64)
+{
+ sqn[5] = (sqn64 >> 0) & 0xff;
+ sqn[4] = (sqn64 >> 8) & 0xff;
+ sqn[3] = (sqn64 >> 16) & 0xff;
+ sqn[2] = (sqn64 >> 24) & 0xff;
+ sqn[1] = (sqn64 >> 32) & 0xff;
+ sqn[0] = (sqn64 >> 40) & 0xff;
+}
+
+static uint64_t sqn_48bit_to_u64(const uint8_t *sqn)
+{
+ uint64_t sqn64;
+
+ sqn64 = sqn[0];
+ sqn64 <<= 8;
+ sqn64 |= sqn[1];
+ sqn64 <<= 8;
+ sqn64 |= sqn[2];
+ sqn64 <<= 8;
+ sqn64 |= sqn[3];
+ sqn64 <<= 8;
+ sqn64 |= sqn[4];
+ sqn64 <<= 8;
+ sqn64 |= sqn[5];
+
+ return sqn64;
+}
+
+
+static int milenage_gen_vec(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *_rand)
+{
+ size_t res_len = sizeof(vec->res);
+ uint8_t sqn[6];
+ int rc;
+
+ sqn_u64_to_48bit(sqn, aud->u.umts.sqn);
+ milenage_generate(aud->u.umts.opc, aud->u.umts.amf, aud->u.umts.k,
+ sqn, _rand,
+ vec->autn, vec->ik, vec->ck, vec->res, &res_len);
+ vec->res_len = res_len;
+ rc = gsm_milenage(aud->u.umts.opc, aud->u.umts.k, _rand, vec->sres, vec->kc);
+ if (rc < 0)
+ return rc;
+
+ vec->auth_types = OSMO_AUTH_TYPE_UMTS | OSMO_AUTH_TYPE_GSM;
+ aud->u.umts.sqn++;
+
+ return 0;
+}
+
+static int milenage_gen_vec_auts(struct osmo_auth_vector *vec,
+ struct osmo_sub_auth_data *aud,
+ const uint8_t *auts, const uint8_t *rand_auts,
+ const uint8_t *_rand)
+{
+ uint8_t sqn_out[6];
+ int rc;
+
+ rc = milenage_auts(aud->u.umts.opc, aud->u.umts.k,
+ rand_auts, auts, sqn_out);
+ if (rc < 0)
+ return rc;
+
+ aud->u.umts.sqn = sqn_48bit_to_u64(sqn_out) + 1;
+
+ return milenage_gen_vec(vec, aud, _rand);
+}
+
+static struct osmo_auth_impl milenage_alg = {
+ .algo = OSMO_AUTH_ALG_MILENAGE,
+ .name = "MILENAGE (libosmogsm built-in)",
+ .priority = 1000,
+ .gen_vec = &milenage_gen_vec,
+ .gen_vec_auts = &milenage_gen_vec_auts,
+};
+
+static __attribute__((constructor)) void on_dso_load_milenage(void)
+{
+ osmo_auth_register(&milenage_alg);
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/comp128.c b/Src/osmolib/src/shared/libosmocore/src/gsm/comp128.c
index 5d5680c..b7a2382 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsm/comp128.c
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/comp128.c
@@ -185,7 +185,7 @@ _comp128_permutation(uint8_t *x, uint8_t *bits)
}
void
-comp128(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc)
+comp128(const uint8_t *ki, const uint8_t *rand, uint8_t *sres, uint8_t *kc)
{
int i;
uint8_t x[32], bits[128];
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smc.c b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smc.c
new file mode 100644
index 0000000..54e6129
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smc.c
@@ -0,0 +1,539 @@
+/* Point-to-Point (PP) Short Message Service (SMS)
+ * Support on Mobile Radio Interface
+ * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
+
+/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* Notes on msg:
+ *
+ * Messages from lower layer are freed by lower layer.
+ *
+ * Messages to upper layer are freed after upper layer call returns, so upper
+ * layer cannot use data after returning. Upper layer must not free the msg.
+ *
+ * This implies: Lower layer messages can be forwarded to upper layer.
+ *
+ * Upper layer messages are freed by lower layer, so they must not be freed
+ * after calling lower layer.
+ *
+ *
+ * Notes on release:
+ *
+ * Whenever the process returns to IDLE, the MM connection is released using
+ * MMSMS-REL-REQ. It is allowed to destroy this process while processing
+ * this message.
+ *
+ * There is expeption, if MMSMS-REL-IND is received from lower layer, the
+ * process returns to IDLE without sending MMSMS-REL-REQ.
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/timer.h>
+
+#include <osmocom/gsm/gsm0411_utils.h>
+#include <osmocom/gsm/gsm0411_smc.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+
+static void cp_timer_expired(void *data);
+
+#define MAX_SMS_RETRY 2
+
+/* init a new instance */
+void gsm411_smc_init(struct gsm411_smc_inst *inst, int network,
+ int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg),
+ int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type))
+{
+ memset(inst, 0, sizeof(*inst));
+ inst->network = network;
+ inst->cp_max_retr = MAX_SMS_RETRY;
+ inst->cp_tc1 = GSM411_TMR_TC1A_SEC / (inst->cp_max_retr + 1);
+ inst->cp_state = GSM411_CPS_IDLE;
+ inst->mn_recv = mn_recv;
+ inst->mm_send = mm_send;
+
+ LOGP(DLSMS, LOGL_INFO, "New SMC instance created\n");
+}
+
+/* clear instance */
+void gsm411_smc_clear(struct gsm411_smc_inst *inst)
+{
+ LOGP(DLSMS, LOGL_INFO, "Clear SMC instance\n");
+
+ osmo_timer_del(&inst->cp_timer);
+
+ /* free stored msg */
+ if (inst->cp_msg) {
+ LOGP(DLSMS, LOGL_INFO, "Dropping pending message\n");
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+}
+
+const char *smc_state_names[] = {
+ "IDLE",
+ "MM_CONN_PENDING",
+ "WAIT_CP_ACK",
+ "MM_ESTABLISHED",
+};
+
+const struct value_string gsm411_cp_cause_strs[] = {
+ { GSM411_CP_CAUSE_NET_FAIL, "Network Failure" },
+ { GSM411_CP_CAUSE_CONGESTION, "Congestion" },
+ { GSM411_CP_CAUSE_INV_TRANS_ID, "Invalid Transaction ID" },
+ { GSM411_CP_CAUSE_SEMANT_INC_MSG, "Semantically Incorrect Message" },
+ { GSM411_CP_CAUSE_INV_MAND_INF, "Invalid Mandatory Information" },
+ { GSM411_CP_CAUSE_MSGTYPE_NOTEXIST, "Message Type doesn't exist" },
+ { GSM411_CP_CAUSE_MSG_INCOMP_STATE,
+ "Message incompatible with protocol state" },
+ { GSM411_CP_CAUSE_IE_NOTEXIST, "IE does not exist" },
+ { GSM411_CP_CAUSE_PROTOCOL_ERR, "Protocol Error" },
+ { 0, 0 }
+};
+
+static void new_cp_state(struct gsm411_smc_inst *inst,
+ enum gsm411_cp_state state)
+{
+ LOGP(DLSMS, LOGL_INFO, "New CP state %s -> %s\n",
+ smc_state_names[inst->cp_state], smc_state_names[state]);
+ inst->cp_state = state;
+}
+
+static int gsm411_tx_cp_error(struct gsm411_smc_inst *inst, uint8_t cause)
+{
+ struct msgb *nmsg = gsm411_msgb_alloc();
+ uint8_t *causep;
+
+ LOGP(DLSMS, LOGL_NOTICE, "TX CP-ERROR, cause %d (%s)\n", cause,
+ get_value_string(gsm411_cp_cause_strs, cause));
+
+ causep = msgb_put(nmsg, 1);
+ *causep = cause;
+
+ return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
+ GSM411_MT_CP_ERROR);
+}
+
+/* etablish SMC connection */
+static int gsm411_mnsms_est_req(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ struct msgb *nmsg;
+
+ if (inst->cp_msg) {
+ LOGP(DLSMS, LOGL_FATAL, "EST REQ, but we already have an "
+ "cp_msg. This should never happen, please fix!\n");
+ msgb_free(inst->cp_msg);
+ }
+
+ inst->cp_msg = msg;
+ new_cp_state(inst, GSM411_CPS_MM_CONN_PENDING);
+ /* clear stored release flag */
+ inst->cp_rel = 0;
+ /* send MMSMS_EST_REQ */
+ nmsg = gsm411_msgb_alloc();
+ return inst->mm_send(inst, GSM411_MMSMS_EST_REQ, nmsg, 0);
+}
+
+static int gsm411_mmsms_send_msg(struct gsm411_smc_inst *inst)
+{
+ struct msgb *nmsg;
+
+ LOGP(DLSMS, LOGL_INFO, "Send CP data\n");
+ /* reset retry counter */
+ if (inst->cp_state != GSM411_CPS_WAIT_CP_ACK)
+ inst->cp_retx = 0;
+ /* 5.2.3.1.2: enter MO-wait for CP-ACK */
+ /* 5.2.3.2.3: enter MT-wait for CP-ACK */
+ new_cp_state(inst, GSM411_CPS_WAIT_CP_ACK);
+ inst->cp_timer.data = inst;
+ inst->cp_timer.cb = cp_timer_expired;
+ /* 5.3.2.1: Set Timer TC1A */
+ osmo_timer_schedule(&inst->cp_timer, inst->cp_tc1, 0);
+ /* clone cp_msg */
+ nmsg = gsm411_msgb_alloc();
+ memcpy(msgb_put(nmsg, inst->cp_msg->len), inst->cp_msg->data,
+ inst->cp_msg->len);
+ /* send MMSMS_DATA_REQ with CP-DATA */
+ return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
+ GSM411_MT_CP_DATA);
+}
+
+static int gsm411_mmsms_est_cnf(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ if (!inst->cp_msg) {
+ LOGP(DLSMS, LOGL_FATAL, "EST CNF, but we have no cp_msg. This "
+ "should never happen, please fix!\n");
+ return -EINVAL;
+ }
+
+ return gsm411_mmsms_send_msg(inst);
+}
+
+/* SMC TC1* is expired */
+static void cp_timer_expired(void *data)
+{
+ struct gsm411_smc_inst *inst = data;
+ struct msgb *nmsg;
+
+ if (inst->cp_retx == inst->cp_max_retr) {
+
+ LOGP(DLSMS, LOGL_INFO, "TC1* timeout, no more retries.\n");
+ /* 5.3.2.1: enter idle state */
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* indicate error */
+ nmsg = gsm411_msgb_alloc();
+ inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
+ msgb_free(nmsg);
+ /* free pending stored msg */
+ if (inst->cp_msg) {
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+ /* release MM connection */
+ nmsg = gsm411_msgb_alloc();
+ inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
+ return;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "TC1* timeout, retrying...\n");
+ inst->cp_retx++;
+ gsm411_mmsms_est_cnf(inst, NULL);
+}
+
+static int gsm411_mmsms_cp_ack(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ /* free stored msg */
+ if (inst->cp_msg) {
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "Received CP-ACK\n");
+ /* 5.3.2.1 enter MM Connection established */
+ new_cp_state(inst, GSM411_CPS_MM_ESTABLISHED);
+ /* 5.3.2.1: Reset Timer TC1* */
+ osmo_timer_del(&inst->cp_timer);
+
+ /* pending release? */
+ if (inst->cp_rel) {
+ struct msgb *nmsg;
+
+ LOGP(DLSMS, LOGL_INFO, "We have pending release.\n");
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* release MM connection */
+ nmsg = gsm411_msgb_alloc();
+ return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
+ }
+
+ return 0;
+}
+
+static int gsm411_mmsms_cp_data(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ struct msgb *nmsg;
+ int mt = GSM411_MNSMS_DATA_IND;
+
+ LOGP(DLSMS, LOGL_INFO, "Received CP-DATA\n");
+ /* 5.3.1 enter MM Connection established (if idle) */
+ if (inst->cp_state == GSM411_CPS_IDLE) {
+ new_cp_state(inst, GSM411_CPS_MM_ESTABLISHED);
+ mt = GSM411_MNSMS_EST_IND;
+ /* clear stored release flag */
+ inst->cp_rel = 0;
+ }
+ /* send MMSMS_DATA_REQ (CP ACK) */
+ nmsg = gsm411_msgb_alloc();
+ inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg, GSM411_MT_CP_ACK);
+ /* indicate data */
+ inst->mn_recv(inst, mt, msg);
+
+ return 0;
+}
+
+/* send CP DATA */
+static int gsm411_mnsms_data_req(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ if (inst->cp_msg) {
+ LOGP(DLSMS, LOGL_FATAL, "DATA REQ, but we already have an "
+ "cp_msg. This should never happen, please fix!\n");
+ msgb_free(inst->cp_msg);
+ }
+
+ /* store and send */
+ inst->cp_msg = msg;
+ return gsm411_mmsms_send_msg(inst);
+}
+
+/* release SMC connection */
+static int gsm411_mnsms_rel_req(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ struct msgb *nmsg;
+
+ msgb_free(msg);
+
+ /* discard silently */
+ if (inst->cp_state == GSM411_CPS_IDLE)
+ return 0;
+
+ /* store release, until established or released */
+ if (inst->cp_state != GSM411_CPS_MM_ESTABLISHED) {
+ LOGP(DLSMS, LOGL_NOTICE, "Cannot release yet.\n");
+ inst->cp_rel = 1;
+ return 0;
+ }
+
+ /* free stored msg */
+ if (inst->cp_msg) {
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* release MM connection */
+ nmsg = gsm411_msgb_alloc();
+ return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
+}
+
+static int gsm411_mmsms_cp_error(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ struct msgb *nmsg;
+
+ /* free stored msg */
+ if (inst->cp_msg) {
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "Received CP-ERROR\n");
+ /* 5.3.4 enter idle */
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* indicate error */
+ inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, msg);
+ /* release MM connection */
+ nmsg = gsm411_msgb_alloc();
+ return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
+}
+
+static int gsm411_mmsms_rel_ind(struct gsm411_smc_inst *inst, struct msgb *msg)
+{
+ struct msgb *nmsg;
+
+ /* free stored msg */
+ if (inst->cp_msg) {
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "MM layer is released\n");
+ /* 5.3.4 enter idle */
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* indicate error */
+ nmsg = gsm411_msgb_alloc();
+ inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
+ msgb_free(nmsg);
+
+ return 0;
+}
+
+/* abort SMC connection */
+static int gsm411_mnsms_abort_req(struct gsm411_smc_inst *inst,
+ struct msgb *msg)
+{
+ struct msgb *nmsg;
+
+ /* free stored msg */
+ if (inst->cp_msg) {
+ msgb_free(inst->cp_msg);
+ inst->cp_msg = NULL;
+ }
+
+ /* 5.3.4 go idle */
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* send MMSMS_DATA_REQ with CP-ERROR */
+ inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, msg, GSM411_MT_CP_ERROR);
+ /* release MM connection */
+ nmsg = gsm411_msgb_alloc();
+ return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
+}
+
+/* statefull handling for MNSMS SAP messages */
+static struct smcdownstate {
+ uint32_t states;
+ int type;
+ const char *name;
+ int (*rout) (struct gsm411_smc_inst *inst,
+ struct msgb *msg);
+} smcdownstatelist[] = {
+ /* establish request */
+ {SBIT(GSM411_CPS_IDLE),
+ GSM411_MNSMS_EST_REQ,
+ "MNSMS-EST-REQ", gsm411_mnsms_est_req},
+
+ /* release request */
+ {ALL_STATES,
+ GSM411_MNSMS_REL_REQ,
+ "MNSMS-REL-REQ", gsm411_mnsms_rel_req},
+
+ /* data request */
+ {SBIT(GSM411_CPS_MM_ESTABLISHED),
+ GSM411_MNSMS_DATA_REQ,
+ "MNSMS-DATA-REQ", gsm411_mnsms_data_req},
+
+ /* abort request */
+ {ALL_STATES - SBIT(GSM411_CPS_IDLE),
+ GSM411_MNSMS_ABORT_REQ,
+ "MNSMS-ABORT-REQ", gsm411_mnsms_abort_req},
+};
+
+#define SMCDOWNSLLEN \
+ (sizeof(smcdownstatelist) / sizeof(struct smcdownstate))
+
+/* message from upper layer */
+int gsm411_smc_send(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg)
+{
+ int i, rc;
+
+ /* find function for current state and message */
+ for (i = 0; i < SMCDOWNSLLEN; i++) {
+ if ((msg_type == smcdownstatelist[i].type)
+ && (SBIT(inst->cp_state) & smcdownstatelist[i].states))
+ break;
+ }
+ if (i == SMCDOWNSLLEN) {
+ LOGP(DLSMS, LOGL_NOTICE, "Message %u unhandled at this state "
+ "%s.\n", msg_type, smc_state_names[inst->cp_state]);
+ msgb_free(msg);
+ return 0;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
+ smcdownstatelist[i].name, smc_state_names[inst->cp_state]);
+
+ rc = smcdownstatelist[i].rout(inst, msg);
+
+ return rc;
+}
+
+/* statefull handling for MMSMS SAP messages */
+static struct smcdatastate {
+ uint32_t states;
+ int type, cp_type;
+ const char *name;
+ int (*rout) (struct gsm411_smc_inst *inst,
+ struct msgb *msg);
+} smcdatastatelist[] = {
+ /* establish confirm */
+ {SBIT(GSM411_CPS_MM_CONN_PENDING),
+ GSM411_MMSMS_EST_CNF, 0,
+ "MMSMS-EST-CNF", gsm411_mmsms_est_cnf},
+
+ /* establish indication (CP DATA) */
+ {SBIT(GSM411_CPS_IDLE),
+ GSM411_MMSMS_EST_IND, GSM411_MT_CP_DATA,
+ "MMSMS-EST-IND (CP DATA)", gsm411_mmsms_cp_data},
+
+ /* data indication (CP DATA) */
+ {SBIT(GSM411_CPS_MM_ESTABLISHED),
+ GSM411_MMSMS_DATA_IND, GSM411_MT_CP_DATA,
+ "MMSMS-DATA-IND (CP DATA)", gsm411_mmsms_cp_data},
+
+ /* data indication (CP ACK) */
+ {SBIT(GSM411_CPS_WAIT_CP_ACK),
+ GSM411_MMSMS_DATA_IND, GSM411_MT_CP_ACK,
+ "MMSMS-DATA-IND (CP ACK)", gsm411_mmsms_cp_ack},
+
+ /* data indication (CP ERROR) */
+ {ALL_STATES,
+ GSM411_MMSMS_DATA_IND, GSM411_MT_CP_ERROR,
+ "MMSMS-DATA-IND (CP_ERROR)", gsm411_mmsms_cp_error},
+
+ /* release indication */
+ {ALL_STATES - SBIT(GSM411_CPS_IDLE),
+ GSM411_MMSMS_REL_IND, 0,
+ "MMSMS-REL-IND", gsm411_mmsms_rel_ind},
+
+};
+
+#define SMCDATASLLEN \
+ (sizeof(smcdatastatelist) / sizeof(struct smcdatastate))
+
+/* message from lower layer
+ * WARNING: We must not free msg, since it will be performed by the
+ * lower layer. */
+int gsm411_smc_recv(struct gsm411_smc_inst *inst, int msg_type,
+ struct msgb *msg, int cp_msg_type)
+{
+ int i, rc;
+
+ /* find function for current state and message */
+ for (i = 0; i < SMCDATASLLEN; i++) {
+ /* state must machtch, MM message must match
+ * CP msg must match only in case of MMSMS_DATA_IND
+ */
+ if ((msg_type == smcdatastatelist[i].type)
+ && (SBIT(inst->cp_state) & smcdatastatelist[i].states)
+ && (msg_type != GSM411_MMSMS_DATA_IND
+ || cp_msg_type == smcdatastatelist[i].cp_type))
+ break;
+ }
+ if (i == SMCDATASLLEN) {
+ LOGP(DLSMS, LOGL_NOTICE, "Message 0x%x/%u unhandled at this "
+ "state %s.\n", msg_type, cp_msg_type,
+ smc_state_names[inst->cp_state]);
+ if (msg_type == GSM411_MMSMS_EST_IND
+ || msg_type == GSM411_MMSMS_DATA_IND) {
+ struct msgb *nmsg;
+
+ LOGP(DLSMS, LOGL_NOTICE, "RX Unimplemented CP "
+ "msg_type: 0x%02x\n", msg_type);
+ /* 5.3.4 enter idle */
+ new_cp_state(inst, GSM411_CPS_IDLE);
+ /* indicate error */
+ gsm411_tx_cp_error(inst,
+ GSM411_CP_CAUSE_MSGTYPE_NOTEXIST);
+ /* send error indication to upper layer */
+ nmsg = gsm411_msgb_alloc();
+ inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
+ msgb_free(nmsg);
+ /* release MM connection */
+ nmsg = gsm411_msgb_alloc();
+ return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg,
+ 0);
+ }
+ return 0;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
+ smcdatastatelist[i].name, smc_state_names[inst->cp_state]);
+
+ rc = smcdatastatelist[i].rout(inst, msg);
+
+ return rc;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smr.c b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smr.c
new file mode 100644
index 0000000..d5ca923
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_smr.c
@@ -0,0 +1,451 @@
+/* Point-to-Point (PP) Short Message Service (SMS)
+ * Support on Mobile Radio Interface
+ * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
+
+/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* Notes on msg:
+ *
+ * Messages from lower layer are freed by lower layer.
+ *
+ * Messages to upper layer are freed after upper layer call returns, so upper
+ * layer cannot use data after returning. Upper layer must not free the msg.
+ *
+ * This implies: Lower layer messages can be forwarded to upper layer.
+ *
+ * Upper layer messages are freed by lower layer, so they must not be freed
+ * after calling lower layer.
+ *
+ *
+ * Notes on release:
+ *
+ * Sending Abort/Release (MNSMS-ABORT-REQ or MNSMS-REL-REQ) may cause the
+ * lower layer to become IDLE. Then it is allowed to destroy this instance,
+ * so sending this this MUST be the last thing that is done.
+ *
+ */
+
+
+#include <string.h>
+#include <errno.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/gsm/tlv.h>
+
+#include <osmocom/gsm/gsm0411_utils.h>
+#include <osmocom/gsm/gsm0411_smc.h>
+#include <osmocom/gsm/gsm0411_smr.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+
+static void rp_timer_expired(void *data);
+
+/* init a new instance */
+void gsm411_smr_init(struct gsm411_smr_inst *inst, int network,
+ int (*rl_recv) (struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg),
+ int (*mn_send) (struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg))
+{
+ memset(inst, 0, sizeof(*inst));
+ inst->network = network;
+ inst->rp_state = GSM411_RPS_IDLE;
+ inst->rl_recv = rl_recv;
+ inst->mn_send = mn_send;
+ inst->rp_timer.data = inst;
+ inst->rp_timer.cb = rp_timer_expired;
+
+ LOGP(DLSMS, LOGL_INFO, "New SMR instance created\n");
+}
+
+/* clear instance */
+void gsm411_smr_clear(struct gsm411_smr_inst *inst)
+{
+ LOGP(DLSMS, LOGL_INFO, "Clear SMR instance\n");
+
+ osmo_timer_del(&inst->rp_timer);
+}
+
+const char *smr_state_names[] = {
+ "IDLE",
+ "WAIT_FOR_RP_ACK",
+ "illegal state 2"
+ "WAIT_TO_TX_RP_ACK",
+ "WAIT_FOR_RETRANS_T",
+};
+
+const struct value_string gsm411_rp_cause_strs[] = {
+ { GSM411_RP_CAUSE_MO_NUM_UNASSIGNED, "(MO) Number not assigned" },
+ { GSM411_RP_CAUSE_MO_OP_DET_BARR, "(MO) Operator determined barring" },
+ { GSM411_RP_CAUSE_MO_CALL_BARRED, "(MO) Call barred" },
+ { GSM411_RP_CAUSE_MO_SMS_REJECTED, "(MO) SMS rejected" },
+ { GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER, "(MO) Destination out of order" },
+ { GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR, "(MO) Unidentified subscriber" },
+ { GSM411_RP_CAUSE_MO_FACILITY_REJ, "(MO) Facility reject" },
+ { GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR, "(MO) Unknown subscriber" },
+ { GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER, "(MO) Network out of order" },
+ { GSM411_RP_CAUSE_MO_TEMP_FAIL, "(MO) Temporary failure" },
+ { GSM411_RP_CAUSE_MO_CONGESTION, "(MO) Congestion" },
+ { GSM411_RP_CAUSE_MO_RES_UNAVAIL, "(MO) Resource unavailable" },
+ { GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR, "(MO) Requested facility not subscribed" },
+ { GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL, "(MO) Requested facility not implemented" },
+ { GSM411_RP_CAUSE_MO_INTERWORKING, "(MO) Interworking" },
+ /* valid only for MT */
+ { GSM411_RP_CAUSE_MT_MEM_EXCEEDED, "(MT) Memory Exceeded" },
+ /* valid for both directions */
+ { GSM411_RP_CAUSE_INV_TRANS_REF, "Invalid Transaction Reference" },
+ { GSM411_RP_CAUSE_SEMANT_INC_MSG, "Semantically Incorrect Message" },
+ { GSM411_RP_CAUSE_INV_MAND_INF, "Invalid Mandatory Information" },
+ { GSM411_RP_CAUSE_MSGTYPE_NOTEXIST, "Message Type non-existant" },
+ { GSM411_RP_CAUSE_MSG_INCOMP_STATE, "Message incompatible with protocol state" },
+ { GSM411_RP_CAUSE_IE_NOTEXIST, "Information Element not existing" },
+ { GSM411_RP_CAUSE_PROTOCOL_ERR, "Protocol Error" },
+ { 0, NULL }
+};
+
+static void new_rp_state(struct gsm411_smr_inst *inst,
+ enum gsm411_rp_state state)
+{
+ LOGP(DLSMS, LOGL_INFO, "New RP state %s -> %s\n",
+ smr_state_names[inst->rp_state], smr_state_names[state]);
+ inst->rp_state = state;
+
+ /* stop timer when going idle */
+ if (state == GSM411_RPS_IDLE)
+ osmo_timer_del(&inst->rp_timer);
+}
+
+/* Prefix msg with a RP-DATA header and send as CP-DATA */
+static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg,
+ uint8_t rp_msg_type, uint8_t rp_msg_ref,
+ int mnsms_msg_type)
+{
+ struct gsm411_rp_hdr *rp;
+ uint8_t len = msg->len;
+
+ /* GSM 04.11 RP-DATA header */
+ rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
+ rp->len = len + 2;
+ rp->msg_type = rp_msg_type;
+ rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */
+
+ return inst->mn_send(inst, mnsms_msg_type, msg);
+}
+
+static int gsm411_send_rp_error(struct gsm411_smr_inst *inst,
+ uint8_t msg_ref, uint8_t cause)
+{
+ struct msgb *msg = gsm411_msgb_alloc();
+
+ msgb_tv_put(msg, 1, cause);
+
+ LOGP(DLSMS, LOGL_NOTICE, "TX: SMS RP ERROR, cause %d (%s)\n", cause,
+ get_value_string(gsm411_rp_cause_strs, cause));
+
+ return gsm411_rp_sendmsg(inst, msg,
+ (inst->network) ? GSM411_MT_RP_ERROR_MT : GSM411_MT_RP_ERROR_MO,
+ msg_ref, GSM411_MNSMS_DATA_REQ);
+}
+
+static int gsm411_send_release(struct gsm411_smr_inst *inst)
+{
+ struct msgb *msg = gsm411_msgb_alloc();
+
+ LOGP(DLSMS, LOGL_NOTICE, "TX: MNSMS-REL-REQ\n");
+
+ return inst->mn_send(inst, GSM411_MNSMS_REL_REQ, msg);
+}
+
+static int gsm411_send_abort(struct gsm411_smr_inst *inst)
+{
+ struct msgb *msg = gsm411_msgb_alloc();
+
+ msgb_tv_put(msg, 1, 111); //FIXME: better idea ? */
+ LOGP(DLSMS, LOGL_NOTICE, "TX: MNSMS-ABORT-REQ\n");
+
+ return inst->mn_send(inst, GSM411_MNSMS_ABORT_REQ, msg);
+}
+
+static int gsm411_send_report(struct gsm411_smr_inst *inst)
+{
+ struct msgb *msg = gsm411_msgb_alloc();
+
+ LOGP(DLSMS, LOGL_NOTICE, "send empty SM_RL_REPORT_IND\n");
+
+ return inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
+}
+
+static int gsm411_rl_data_req(struct gsm411_smr_inst *inst, struct msgb *msg)
+{
+ LOGP(DLSMS, LOGL_DEBUG, "TX SMS RP-DATA\n");
+ /* start TR1N and enter 'wait for RP-ACK state' */
+ osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR1M);
+ new_rp_state(inst, GSM411_RPS_WAIT_FOR_RP_ACK);
+
+ return inst->mn_send(inst, GSM411_MNSMS_EST_REQ, msg);
+}
+
+static int gsm411_rl_report_req(struct gsm411_smr_inst *inst, struct msgb *msg)
+{
+ LOGP(DLSMS, LOGL_DEBUG, "TX SMS REPORT\n");
+ new_rp_state(inst, GSM411_RPS_IDLE);
+
+ inst->mn_send(inst, GSM411_MNSMS_DATA_REQ, msg);
+ gsm411_send_release(inst);
+ return 0;
+}
+
+static int gsm411_mnsms_est_ind(struct gsm411_smr_inst *inst, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr*)msg->l3h;
+ struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
+ uint8_t msg_type = rp_data->msg_type & 0x07;
+ int rc;
+
+ /* check direction */
+ if (inst->network == (msg_type & 1)) {
+ LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+ gsm411_send_rp_error(inst, rp_data->msg_ref,
+ GSM411_RP_CAUSE_MSG_INCOMP_STATE);
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ gsm411_send_release(inst);
+ return -EINVAL;
+ }
+
+ switch (msg_type) {
+ case GSM411_MT_RP_DATA_MT:
+ case GSM411_MT_RP_DATA_MO:
+ LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-DATA\n");
+ /* start TR2N and enter 'wait to send RP-ACK state' */
+ osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M);
+ new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK);
+ rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg);
+ break;
+ case GSM411_MT_RP_SMMA_MO:
+ LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-SMMA\n");
+ /* start TR2N and enter 'wait to send RP-ACK state' */
+ osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M);
+ new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK);
+ rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg);
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+ gsm411_send_rp_error(inst, rp_data->msg_ref,
+ GSM411_RP_CAUSE_MSGTYPE_NOTEXIST);
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
+static int gsm411_mnsms_data_ind_tx(struct gsm411_smr_inst *inst,
+ struct msgb *msg)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr*)msg->l3h;
+ struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
+ uint8_t msg_type = rp_data->msg_type & 0x07;
+ int rc;
+
+ /* check direction */
+ if (inst->network == (msg_type & 1)) {
+ LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+ gsm411_send_rp_error(inst, rp_data->msg_ref,
+ GSM411_RP_CAUSE_MSG_INCOMP_STATE);
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ gsm411_send_release(inst);
+ return -EINVAL;
+ }
+
+ switch (msg_type) {
+ case GSM411_MT_RP_ACK_MO:
+ case GSM411_MT_RP_ACK_MT:
+ LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-ACK\n");
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
+ gsm411_send_release(inst);
+ return 0;
+ case GSM411_MT_RP_ERROR_MO:
+ case GSM411_MT_RP_ERROR_MT:
+ LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-ERROR\n");
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
+ gsm411_send_release(inst);
+ return 0;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+ gsm411_send_rp_error(inst, rp_data->msg_ref,
+ GSM411_RP_CAUSE_MSGTYPE_NOTEXIST);
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ gsm411_send_release(inst);
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int gsm411_mnsms_error_ind_tx(struct gsm411_smr_inst *inst,
+ struct msgb *msg)
+{
+ LOGP(DLSMS, LOGL_DEBUG, "RX SMS MNSMS-ERROR-IND\n");
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
+ gsm411_send_release(inst);
+ return 0;
+}
+
+static int gsm411_mnsms_error_ind_rx(struct gsm411_smr_inst *inst,
+ struct msgb *msg)
+{
+ LOGP(DLSMS, LOGL_DEBUG, "RX SMS MNSMS-ERROR-IND\n");
+ new_rp_state(inst, GSM411_RPS_IDLE);
+ return inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
+}
+
+/* SMR TR1* is expired */
+static void rp_timer_expired(void *data)
+{
+ struct gsm411_smr_inst *inst = data;
+
+ if (inst->rp_state == GSM411_RPS_WAIT_TO_TX_RP_ACK)
+ LOGP(DLSMS, LOGL_DEBUG, "TR2N\n");
+ else
+ LOGP(DLSMS, LOGL_DEBUG, "TR1N\n");
+ gsm411_send_report(inst);
+ gsm411_send_abort(inst);
+}
+
+/* statefull handling for SM-RL SAP messages */
+static struct smrdownstate {
+ uint32_t states;
+ int type;
+ const char *name;
+ int (*rout) (struct gsm411_smr_inst *inst,
+ struct msgb *msg);
+} smrdownstatelist[] = {
+ /* data request */
+ {SBIT(GSM411_RPS_IDLE),
+ GSM411_SM_RL_DATA_REQ,
+ "SM-RL-DATA_REQ", gsm411_rl_data_req},
+
+ /* report request */
+ {SBIT(GSM411_RPS_WAIT_TO_TX_RP_ACK),
+ GSM411_SM_RL_REPORT_REQ,
+ "SM-RL-REPORT_REQ", gsm411_rl_report_req},
+};
+
+#define SMRDOWNSLLEN \
+ (sizeof(smrdownstatelist) / sizeof(struct smrdownstate))
+
+/* message from upper layer */
+int gsm411_smr_send(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg)
+{
+ int i, rc;
+
+ /* find function for current state and message */
+ for (i = 0; i < SMRDOWNSLLEN; i++) {
+ if ((msg_type == smrdownstatelist[i].type)
+ && (SBIT(inst->rp_state) & smrdownstatelist[i].states))
+ break;
+ }
+ if (i == SMRDOWNSLLEN) {
+ LOGP(DLSMS, LOGL_NOTICE, "Message %u unhandled at this state "
+ "%s.\n", msg_type, smr_state_names[inst->rp_state]);
+ msgb_free(msg);
+ return 0;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
+ smrdownstatelist[i].name, smr_state_names[inst->rp_state]);
+
+ rc = smrdownstatelist[i].rout(inst, msg);
+
+ return rc;
+}
+
+/* statefull handling for MMSMS SAP messages */
+static struct smrdatastate {
+ uint32_t states;
+ int type;
+ const char *name;
+ int (*rout) (struct gsm411_smr_inst *inst,
+ struct msgb *msg);
+} smrdatastatelist[] = {
+ /* establish indication */
+ {SBIT(GSM411_RPS_IDLE),
+ GSM411_MNSMS_EST_IND,
+ "MNSMS-EST-IND", gsm411_mnsms_est_ind},
+
+ /* data indication */
+ {SBIT(GSM411_RPS_WAIT_FOR_RP_ACK),
+ GSM411_MNSMS_DATA_IND,
+ "MNSMS-DATA-IND", gsm411_mnsms_data_ind_tx},
+
+ /* error indication */
+ {SBIT(GSM411_RPS_WAIT_FOR_RP_ACK),
+ GSM411_MNSMS_ERROR_IND,
+ "MNSMS-ERROR-IND", gsm411_mnsms_error_ind_tx},
+
+ /* error indication */
+ {SBIT(GSM411_RPS_WAIT_TO_TX_RP_ACK),
+ GSM411_MNSMS_ERROR_IND,
+ "MNSMS-ERROR-IND", gsm411_mnsms_error_ind_rx},
+
+};
+
+#define SMRDATASLLEN \
+ (sizeof(smrdatastatelist) / sizeof(struct smrdatastate))
+
+/* message from lower layer
+ * WARNING: We must not free msg, since it will be performed by the
+ * lower layer. */
+int gsm411_smr_recv(struct gsm411_smr_inst *inst, int msg_type,
+ struct msgb *msg)
+{
+ int i, rc;
+
+ /* find function for current state and message */
+ for (i = 0; i < SMRDATASLLEN; i++) {
+ /* state must machtch, MM message must match
+ * CP msg must match only in case of MMSMS_DATA_IND
+ */
+ if ((msg_type == smrdatastatelist[i].type)
+ && (SBIT(inst->rp_state) & smrdatastatelist[i].states))
+ break;
+ }
+ if (i == SMRDATASLLEN) {
+ LOGP(DLSMS, LOGL_NOTICE, "Message %u unhandled at this state "
+ "%s.\n", msg_type, smr_state_names[inst->rp_state]);
+ return 0;
+ }
+
+ LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
+ smrdatastatelist[i].name, smr_state_names[inst->rp_state]);
+
+ rc = smrdatastatelist[i].rout(inst, msg);
+
+ return rc;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_utils.c b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_utils.c
new file mode 100644
index 0000000..5076ec8
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0411_utils.c
@@ -0,0 +1,306 @@
+/* Point-to-Point (PP) Short Message Service (SMS)
+ * Support on Mobile Radio Interface
+ * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
+
+/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <time.h>
+#include <string.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+
+#define GSM411_ALLOC_SIZE 1024
+#define GSM411_ALLOC_HEADROOM 128
+
+struct msgb *gsm411_msgb_alloc(void)
+{
+ return msgb_alloc_headroom(GSM411_ALLOC_SIZE, GSM411_ALLOC_HEADROOM,
+ "GSM 04.11");
+}
+
+/* Turn int into semi-octet representation: 98 => 0x89 */
+uint8_t gsm411_bcdify(uint8_t value)
+{
+ uint8_t ret;
+
+ ret = value / 10;
+ ret |= (value % 10) << 4;
+
+ return ret;
+}
+
+/* Turn semi-octet representation into int: 0x89 => 98 */
+uint8_t gsm411_unbcdify(uint8_t value)
+{
+ uint8_t ret;
+
+ if ((value & 0x0F) > 9 || (value >> 4) > 9)
+ LOGP(DLSMS, LOGL_ERROR,
+ "gsm411_unbcdify got too big nibble: 0x%02X\n", value);
+
+ ret = (value&0x0F)*10;
+ ret += value>>4;
+
+ return ret;
+}
+
+/* Generate 03.40 TP-SCTS */
+void gsm340_gen_scts(uint8_t *scts, time_t time)
+{
+ struct tm *tm = gmtime(&time);
+
+ *scts++ = gsm411_bcdify(tm->tm_year % 100);
+ *scts++ = gsm411_bcdify(tm->tm_mon + 1);
+ *scts++ = gsm411_bcdify(tm->tm_mday);
+ *scts++ = gsm411_bcdify(tm->tm_hour);
+ *scts++ = gsm411_bcdify(tm->tm_min);
+ *scts++ = gsm411_bcdify(tm->tm_sec);
+ *scts++ = gsm411_bcdify(0); /* GMT */
+}
+
+/* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */
+time_t gsm340_scts(uint8_t *scts)
+{
+ struct tm tm;
+ uint8_t yr = gsm411_unbcdify(*scts++);
+ int ofs;
+
+ memset(&tm, 0x00, sizeof(struct tm));
+
+ if (yr <= 80)
+ tm.tm_year = 100 + yr;
+ else
+ tm.tm_year = yr;
+ tm.tm_mon = gsm411_unbcdify(*scts++) - 1;
+ tm.tm_mday = gsm411_unbcdify(*scts++);
+ tm.tm_hour = gsm411_unbcdify(*scts++);
+ tm.tm_min = gsm411_unbcdify(*scts++);
+ tm.tm_sec = gsm411_unbcdify(*scts++);
+
+ /* according to gsm 03.40 time zone is
+ "expressed in quarters of an hour" */
+ ofs = gsm411_unbcdify(*scts++) * 15*60;
+
+ return mktime(&tm) - ofs;
+}
+
+/* Return the default validity period in minutes */
+static unsigned long gsm340_vp_default(void)
+{
+ unsigned long minutes;
+ /* Default validity: two days */
+ minutes = 24 * 60 * 2;
+ return minutes;
+}
+
+/* Decode validity period format 'relative' */
+static unsigned long gsm340_vp_relative(uint8_t *sms_vp)
+{
+ /* Chapter 9.2.3.12.1 */
+ uint8_t vp;
+ unsigned long minutes;
+
+ vp = *(sms_vp);
+ if (vp <= 143)
+ minutes = vp + 1 * 5;
+ else if (vp <= 167)
+ minutes = 12*60 + (vp-143) * 30;
+ else if (vp <= 196)
+ minutes = vp-166 * 60 * 24;
+ else
+ minutes = vp-192 * 60 * 24 * 7;
+ return minutes;
+}
+
+/* Decode validity period format 'absolute' */
+static unsigned long gsm340_vp_absolute(uint8_t *sms_vp)
+{
+ /* Chapter 9.2.3.12.2 */
+ time_t expires, now;
+ unsigned long minutes;
+
+ expires = gsm340_scts(sms_vp);
+ now = time(NULL);
+ if (expires <= now)
+ minutes = 0;
+ else
+ minutes = (expires-now)/60;
+ return minutes;
+}
+
+/* Decode validity period format 'relative in integer representation' */
+static unsigned long gsm340_vp_relative_integer(uint8_t *sms_vp)
+{
+ uint8_t vp;
+ unsigned long minutes;
+ vp = *(sms_vp);
+ if (vp == 0) {
+ LOGP(DLSMS, LOGL_ERROR,
+ "reserved relative_integer validity period\n");
+ return gsm340_vp_default();
+ }
+ minutes = vp/60;
+ return minutes;
+}
+
+/* Decode validity period format 'relative in semi-octet representation' */
+static unsigned long gsm340_vp_relative_semioctet(uint8_t *sms_vp)
+{
+ unsigned long minutes;
+ minutes = gsm411_unbcdify(*sms_vp++)*60; /* hours */
+ minutes += gsm411_unbcdify(*sms_vp++); /* minutes */
+ minutes += gsm411_unbcdify(*sms_vp++)/60; /* seconds */
+ return minutes;
+}
+
+/* decode validity period. return minutes */
+unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp)
+{
+ uint8_t fi; /* functionality indicator */
+
+ switch (sms_vpf) {
+ case GSM340_TP_VPF_RELATIVE:
+ return gsm340_vp_relative(sms_vp);
+ case GSM340_TP_VPF_ABSOLUTE:
+ return gsm340_vp_absolute(sms_vp);
+ case GSM340_TP_VPF_ENHANCED:
+ /* Chapter 9.2.3.12.3 */
+ fi = *sms_vp++;
+ /* ignore additional fi */
+ if (fi & (1<<7)) sms_vp++;
+ /* read validity period format */
+ switch (fi & 0x7) {
+ case 0x0:
+ return gsm340_vp_default(); /* no vpf specified */
+ case 0x1:
+ return gsm340_vp_relative(sms_vp);
+ case 0x2:
+ return gsm340_vp_relative_integer(sms_vp);
+ case 0x3:
+ return gsm340_vp_relative_semioctet(sms_vp);
+ default:
+ /* The GSM spec says that the SC should reject any
+ unsupported and/or undefined values. FIXME */
+ LOGP(DLSMS, LOGL_ERROR,
+ "Reserved enhanced validity period format\n");
+ return gsm340_vp_default();
+ }
+ case GSM340_TP_VPF_NONE:
+ default:
+ return gsm340_vp_default();
+ }
+}
+
+/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
+enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs)
+{
+ uint8_t cgbits = dcs >> 4;
+ enum sms_alphabet alpha = DCS_NONE;
+
+ if ((cgbits & 0xc) == 0) {
+ if (cgbits & 2) {
+ LOGP(DLSMS, LOGL_NOTICE,
+ "Compressed SMS not supported yet\n");
+ return 0xffffffff;
+ }
+
+ switch ((dcs >> 2)&0x03) {
+ case 0:
+ alpha = DCS_7BIT_DEFAULT;
+ break;
+ case 1:
+ alpha = DCS_8BIT_DATA;
+ break;
+ case 2:
+ alpha = DCS_UCS2;
+ break;
+ }
+ } else if (cgbits == 0xc || cgbits == 0xd)
+ alpha = DCS_7BIT_DEFAULT;
+ else if (cgbits == 0xe)
+ alpha = DCS_UCS2;
+ else if (cgbits == 0xf) {
+ if (dcs & 4)
+ alpha = DCS_8BIT_DATA;
+ else
+ alpha = DCS_7BIT_DEFAULT;
+ }
+
+ return alpha;
+}
+
+/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */
+int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type,
+ uint8_t plan, const char *number)
+{
+ int len_in_bytes;
+
+ /* prevent buffer overflows */
+ if (strlen(number) > 20)
+ number = "";
+
+// oa[1] = 0xb9; /* networks-specific number, private numbering plan */
+ oa[1] = 0x80 | (type << 4) | plan;
+
+ len_in_bytes = gsm48_encode_bcd_number(oa, oa_len, 1, number);
+
+ /* GSM 03.40 tells us the length is in 'useful semi-octets' */
+ oa[0] = strlen(number) & 0xff;
+
+ return len_in_bytes;
+}
+
+/* Prefix msg with a RP header */
+int gsm411_push_rp_header(struct msgb *msg, uint8_t rp_msg_type,
+ uint8_t rp_msg_ref)
+{
+ struct gsm411_rp_hdr *rp;
+ uint8_t len = msg->len;
+
+ /* GSM 04.11 RP-DATA header */
+ rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
+ rp->len = len + 2;
+ rp->msg_type = rp_msg_type;
+ rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */
+
+ return 0;
+}
+
+/* Prefix msg with a 04.08/04.11 CP header */
+int gsm411_push_cp_header(struct msgb *msg, uint8_t proto, uint8_t trans,
+ uint8_t msg_type)
+{
+ struct gsm48_hdr *gh;
+
+ gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
+ /* Outgoing needs the highest bit set */
+ gh->proto_discr = proto | (trans << 4);
+ gh->msg_type = msg_type;
+
+ return 0;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0808.c b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0808.c
index 01221bd..3009827 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0808.c
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm0808.c
@@ -27,69 +27,52 @@
#define BSSMAP_MSG_SIZE 512
#define BSSMAP_MSG_HEADROOM 128
-static void put_data_16(uint8_t *data, const uint16_t val)
-{
- memcpy(data, &val, sizeof(val));
-}
-
struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci)
{
- uint8_t *data;
- uint8_t *ci;
struct msgb* msg;
- struct gsm48_loc_area_id *lai;
+ struct {
+ uint8_t ident;
+ struct gsm48_loc_area_id lai;
+ uint16_t ci;
+ } __attribute__ ((packed)) lai_ci;
msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
"bssmap cmpl l3");
if (!msg)
return NULL;
- /* create the bssmap header */
- msg->l3h = msgb_put(msg, 2);
- msg->l3h[0] = 0x0;
-
/* create layer 3 header */
- data = msgb_put(msg, 1);
- data[0] = BSS_MAP_MSG_COMPLETE_LAYER_3;
+ msgb_v_put(msg, BSS_MAP_MSG_COMPLETE_LAYER_3);
/* create the cell header */
- data = msgb_put(msg, 3);
- data[0] = GSM0808_IE_CELL_IDENTIFIER;
- data[1] = 1 + sizeof(*lai) + 2;
- data[2] = CELL_IDENT_WHOLE_GLOBAL;
-
- lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
- gsm48_generate_lai(lai, cc, nc, lac);
-
- ci = msgb_put(msg, 2);
- put_data_16(ci, htons(_ci));
+ lai_ci.ident = CELL_IDENT_WHOLE_GLOBAL;
+ gsm48_generate_lai(&lai_ci.lai, cc, nc, lac);
+ lai_ci.ci = htons(_ci);
+ msgb_tlv_put(msg, GSM0808_IE_CELL_IDENTIFIER, sizeof(lai_ci),
+ (uint8_t *) &lai_ci);
/* copy the layer3 data */
- data = msgb_put(msg, msgb_l3len(msg_l3) + 2);
- data[0] = GSM0808_IE_LAYER_3_INFORMATION;
- data[1] = msgb_l3len(msg_l3);
- memcpy(&data[2], msg_l3->l3h, data[1]);
+ msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION,
+ msgb_l3len(msg_l3), msg_l3->l3h);
- /* update the size */
- msg->l3h[1] = msgb_l3len(msg) - 2;
+ /* push the bssmap header */
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
return msg;
}
struct msgb *gsm0808_create_reset(void)
{
+ uint8_t cause = GSM0808_CAUSE_EQUIPMENT_FAILURE;
struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
"bssmap: reset");
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 6);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 0x04;
- msg->l3h[2] = 0x30;
- msg->l3h[3] = 0x04;
- msg->l3h[4] = 0x01;
- msg->l3h[5] = 0x20;
+ msgb_v_put(msg, BSS_MAP_MSG_RESET);
+ msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
+
return msg;
}
@@ -97,13 +80,12 @@ struct msgb *gsm0808_create_clear_complete(void)
{
struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
"bssmap: clear complete");
+ uint8_t val = BSS_MAP_MSG_CLEAR_COMPLETE;
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 3);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 1;
- msg->l3h[2] = BSS_MAP_MSG_CLEAR_COMPLETE;
+ msg->l3h = msg->data;
+ msgb_tlv_put(msg, BSSAP_MSG_BSS_MANAGEMENT, 1, &val);
return msg;
}
@@ -118,6 +100,7 @@ struct msgb *gsm0808_create_clear_command(uint8_t reason)
msg->l3h = msgb_tv_put(msg, BSSAP_MSG_BSS_MANAGEMENT, 4);
msgb_v_put(msg, BSS_MAP_MSG_CLEAR_CMD);
msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &reason);
+
return msg;
}
@@ -129,26 +112,20 @@ struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id)
return NULL;
/* send response with BSS override for A5/1... cheating */
- msg->l3h = msgb_put(msg, 3);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 0xff;
- msg->l3h[2] = BSS_MAP_MSG_CIPHER_MODE_COMPLETE;
+ msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_COMPLETE);
/* include layer3 in case we have at least two octets */
if (layer3 && msgb_l3len(layer3) > 2) {
- msg->l4h = msgb_put(msg, msgb_l3len(layer3) + 2);
- msg->l4h[0] = GSM0808_IE_LAYER_3_MESSAGE_CONTENTS;
- msg->l4h[1] = msgb_l3len(layer3);
- memcpy(&msg->l4h[2], layer3->l3h, msgb_l3len(layer3));
+ msg->l4h = msgb_tlv_put(msg, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS,
+ msgb_l3len(layer3), layer3->l3h);
}
/* and the optional BSS message */
- msg->l4h = msgb_put(msg, 2);
- msg->l4h[0] = GSM0808_IE_CHOSEN_ENCR_ALG;
- msg->l4h[1] = alg_id;
+ msgb_tv_put(msg, GSM0808_IE_CHOSEN_ENCR_ALG, alg_id);
+
+ /* pre-pend the header */
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
- /* update the size */
- msg->l3h[1] = msgb_l3len(msg) - 2;
return msg;
}
@@ -159,32 +136,29 @@ struct msgb *gsm0808_create_cipher_reject(uint8_t cause)
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 4);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 2;
- msg->l3h[2] = BSS_MAP_MSG_CIPHER_MODE_REJECT;
- msg->l3h[3] = cause;
+ msgb_tv_put(msg, BSS_MAP_MSG_CIPHER_MODE_REJECT, cause);
+
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
return msg;
}
-struct msgb *gsm0808_create_classmark_update(const uint8_t *classmark_data, uint8_t length)
+struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
+ const uint8_t *cm3, uint8_t cm3_len)
{
struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
"classmark-update");
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 3);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 0xff;
- msg->l3h[2] = BSS_MAP_MSG_CLASSMARK_UPDATE;
+ msgb_v_put(msg, BSS_MAP_MSG_CLASSMARK_UPDATE);
+ msgb_tlv_put(msg, GSM0808_IE_CLASSMARK_INFORMATION_T2, cm2_len, cm2);
+ if (cm3)
+ msgb_tlv_put(msg, GSM0808_IE_CLASSMARK_INFORMATION_T3,
+ cm3_len, cm3);
- msg->l4h = msgb_put(msg, length);
- memcpy(msg->l4h, classmark_data, length);
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
- /* update the size */
- msg->l3h[1] = msgb_l3len(msg) - 2;
return msg;
}
@@ -195,12 +169,11 @@ struct msgb *gsm0808_create_sapi_reject(uint8_t link_id)
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 5);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 3;
- msg->l3h[2] = BSS_MAP_MSG_SAPI_N_REJECT;
- msg->l3h[3] = link_id;
- msg->l3h[4] = GSM0808_CAUSE_BSS_NOT_EQUIPPED;
+ msgb_v_put(msg, BSS_MAP_MSG_SAPI_N_REJECT);
+ msgb_v_put(msg, link_id);
+ msgb_v_put(msg, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
+
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
return msg;
}
@@ -209,78 +182,56 @@ struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
uint8_t chosen_channel, uint8_t encr_alg_id,
uint8_t speech_mode)
{
- uint8_t *data;
-
- struct msgb *msg = msgb_alloc(35, "bssmap: ass compl");
+ struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+ "bssmap: ass compl");
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 3);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 0xff;
- msg->l3h[2] = BSS_MAP_MSG_ASSIGMENT_COMPLETE;
+ msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_COMPLETE);
/* write 3.2.2.22 */
- data = msgb_put(msg, 2);
- data[0] = GSM0808_IE_RR_CAUSE;
- data[1] = rr_cause;
+ msgb_tv_put(msg, GSM0808_IE_RR_CAUSE, rr_cause);
/* write cirtcuit identity code 3.2.2.2 */
/* write cell identifier 3.2.2.17 */
/* write chosen channel 3.2.2.33 when BTS picked it */
- data = msgb_put(msg, 2);
- data[0] = GSM0808_IE_CHOSEN_CHANNEL;
- data[1] = chosen_channel;
+ msgb_tv_put(msg, GSM0808_IE_CHOSEN_CHANNEL, chosen_channel);
/* write chosen encryption algorithm 3.2.2.44 */
- data = msgb_put(msg, 2);
- data[0] = GSM0808_IE_CHOSEN_ENCR_ALG;
- data[1] = encr_alg_id;
+ msgb_tv_put(msg, GSM0808_IE_CHOSEN_ENCR_ALG, encr_alg_id);
/* write circuit pool 3.2.2.45 */
/* write speech version chosen: 3.2.2.51 when BTS picked it */
- if (speech_mode != 0) {
- data = msgb_put(msg, 2);
- data[0] = GSM0808_IE_SPEECH_VERSION;
- data[1] = speech_mode;
- }
+ if (speech_mode != 0)
+ msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode);
/* write LSA identifier 3.2.2.15 */
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
- /* update the size */
- msg->l3h[1] = msgb_l3len(msg) - 2;
return msg;
}
struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause)
{
- uint8_t *data;
struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
"bssmap: ass fail");
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 6);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 0xff;
- msg->l3h[2] = BSS_MAP_MSG_ASSIGMENT_FAILURE;
- msg->l3h[3] = GSM0808_IE_CAUSE;
- msg->l3h[4] = 1;
- msg->l3h[5] = cause;
+ msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_FAILURE);
+ msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
/* RR cause 3.2.2.22 */
- if (rr_cause) {
- data = msgb_put(msg, 2);
- data[0] = GSM0808_IE_RR_CAUSE;
- data[1] = *rr_cause;
- }
+ if (rr_cause)
+ msgb_tv_put(msg, GSM0808_IE_RR_CAUSE, *rr_cause);
/* Circuit pool 3.22.45 */
/* Circuit pool list 3.2.2.46 */
/* update the size */
- msg->l3h[1] = msgb_l3len(msg) - 2;
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
+
return msg;
}
@@ -293,14 +244,10 @@ struct msgb *gsm0808_create_clear_rqst(uint8_t cause)
if (!msg)
return NULL;
- msg->l3h = msgb_put(msg, 2 + 4);
- msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
- msg->l3h[1] = 4;
+ msgb_v_put(msg, BSS_MAP_MSG_CLEAR_RQST);
+ msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
+ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
- msg->l3h[2] = BSS_MAP_MSG_CLEAR_RQST;
- msg->l3h[3] = GSM0808_IE_CAUSE;
- msg->l3h[4] = 1;
- msg->l3h[5] = cause;
return msg;
}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm48.c b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm48.c
index 44baec6..379ed65 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsm/gsm48.c
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/gsm48.c
@@ -406,7 +406,7 @@ int gsm48_construct_ra(uint8_t *buf, const struct gprs_ra_id *raid)
buf[2] = ((mnc / 10) % 10) | ((mnc % 10) << 4);
} else {
buf[1] |= (mnc % 10) << 4;
- buf[2] = ((mnc / 100) % 10) | (((mcc / 10) % 10) << 4);
+ buf[2] = ((mnc / 100) % 10) | (((mnc / 10) % 10) << 4);
}
*(uint16_t *)(buf+3) = htons(raid->lac);
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/lapd_core.c b/Src/osmolib/src/shared/libosmocore/src/gsm/lapd_core.c
new file mode 100644
index 0000000..fb79a2f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/lapd_core.c
@@ -0,0 +1,2170 @@
+/* LAPD core implementation */
+
+/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/*! \addtogroup lapd
+ * @{
+ */
+
+/*! \file lapd.c */
+
+/*!
+ * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
+ *
+ * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
+ * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
+ * received while there is an incomplete rcv_buffer, it is appended to it.
+ *
+ * TX data is stored in the send_queue first. When transmitting a frame,
+ * the first message in the send_queue is moved to the send_buffer. There it
+ * resides until all fragments are acknowledged. Fragments to be sent by I
+ * frames are stored in the tx_hist buffer for resend, if required. Also the
+ * current fragment is copied into the tx_queue. There it resides until it is
+ * forwarded to layer 1.
+ *
+ * In case we have SAPI 0, we only have a window size of 1, so the unack-
+ * nowledged message resides always in the send_buffer. In case of a suspend,
+ * it can be written back to the first position of the send_queue.
+ *
+ * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
+ * asynchronous transfer between layer 1 and layer 2 (serial link), we must
+ * send a frame before layer 1 reaches the right timeslot to send it. So we
+ * move the tx_queue to layer 1 when there is not already a pending frame, and
+ * wait until acknowledge after the frame has been sent. If we receive an
+ * acknowledge, we can send the next frame from the buffer, if any.
+ *
+ * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
+ * will trigger next I frame, if possible.
+ *
+ * T203 is optional. It will be stated when entering MF EST state. It will also
+ * be started when I or S frame is received in that state . It will be
+ * restarted in the lapd_acknowledge() function, in case outstanding frames
+ * will not trigger T200. It will be stoped, when T200 is started in MF EST
+ * state. It will also be stoped when leaving MF EST state.
+ *
+ */
+
+/* Enable this to test content resolution on network side:
+ * - The first SABM is received, UA is dropped.
+ * - The phone repeats SABM, but it's content is wrong, so it is ignored
+ * - The phone repeats SABM again, content is right, so UA is sent.
+ */
+//#define TEST_CONTENT_RESOLUTION_NETWORK
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/gsm/lapd_core.h>
+
+/* TS 04.06 Table 4 / Section 3.8.1 */
+#define LAPD_U_SABM 0x7
+#define LAPD_U_SABME 0xf
+#define LAPD_U_DM 0x3
+#define LAPD_U_UI 0x0
+#define LAPD_U_DISC 0x8
+#define LAPD_U_UA 0xC
+#define LAPD_U_FRMR 0x11
+
+#define LAPD_S_RR 0x0
+#define LAPD_S_RNR 0x1
+#define LAPD_S_REJ 0x2
+
+#define CR_USER2NET_CMD 0
+#define CR_USER2NET_RESP 1
+#define CR_NET2USER_CMD 1
+#define CR_NET2USER_RESP 0
+
+#define LAPD_HEADROOM 56
+
+#define SBIT(a) (1 << a)
+#define ALL_STATES 0xffffffff
+
+static void lapd_t200_cb(void *data);
+static void lapd_t203_cb(void *data);
+static int lapd_send_i(struct lapd_msg_ctx *lctx, int line);
+static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
+
+/* UTILITY FUNCTIONS */
+
+struct msgb *lapd_msgb_alloc(int length, const char *name)
+{
+ /* adding space for padding, FIXME: add as an option */
+ if (length < 21)
+ length = 21;
+ return msgb_alloc_headroom(length + LAPD_HEADROOM, LAPD_HEADROOM, name);
+}
+
+static inline uint8_t do_mod(uint8_t x, uint8_t m)
+{
+ return x & (m - 1);
+}
+
+static inline uint8_t inc_mod(uint8_t x, uint8_t m)
+{
+ return (x + 1) & (m - 1);
+}
+
+static inline uint8_t add_mod(uint8_t x, uint8_t y, uint8_t m)
+{
+ return (x + y) & (m - 1);
+}
+
+static inline uint8_t sub_mod(uint8_t x, uint8_t y, uint8_t m)
+{
+ return (x - y) & (m - 1); /* handle negative results correctly */
+}
+
+static void lapd_dl_flush_send(struct lapd_datalink *dl)
+{
+ struct msgb *msg;
+
+ /* Flush send-queue */
+ while ((msg = msgb_dequeue(&dl->send_queue)))
+ msgb_free(msg);
+
+ /* Clear send-buffer */
+ if (dl->send_buffer) {
+ msgb_free(dl->send_buffer);
+ dl->send_buffer = NULL;
+ }
+}
+
+static void lapd_dl_flush_hist(struct lapd_datalink *dl)
+{
+ unsigned int i;
+
+ for (i = 0; i < dl->range_hist; i++) {
+ if (dl->tx_hist[i].msg) {
+ msgb_free(dl->tx_hist[i].msg);
+ dl->tx_hist[i].msg = NULL;
+ }
+ }
+}
+
+static void lapd_dl_flush_tx(struct lapd_datalink *dl)
+{
+ struct msgb *msg;
+
+ while ((msg = msgb_dequeue(&dl->tx_queue)))
+ msgb_free(msg);
+ lapd_dl_flush_hist(dl);
+}
+
+/* Figure B.2/Q.921 */
+const char *lapd_state_names[] = {
+ "LAPD_STATE_NULL",
+ "LAPD_STATE_TEI_UNASS",
+ "LAPD_STATE_ASS_TEI_WAIT",
+ "LAPD_STATE_EST_TEI_WAIT",
+ "LAPD_STATE_IDLE",
+ "LAPD_STATE_SABM_SENT",
+ "LAPD_STATE_DISC_SENT",
+ "LAPD_STATE_MF_EST",
+ "LAPD_STATE_TIMER_RECOV",
+
+};
+
+static void lapd_start_t200(struct lapd_datalink *dl)
+{
+ if (osmo_timer_pending(&dl->t200))
+ return;
+ LOGP(DLLAPD, LOGL_INFO, "start T200\n");
+ osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec);
+}
+
+static void lapd_start_t203(struct lapd_datalink *dl)
+{
+ if (osmo_timer_pending(&dl->t203))
+ return;
+ LOGP(DLLAPD, LOGL_INFO, "start T203\n");
+ osmo_timer_schedule(&dl->t203, dl->t203_sec, dl->t203_usec);
+}
+
+static void lapd_stop_t200(struct lapd_datalink *dl)
+{
+ if (!osmo_timer_pending(&dl->t200))
+ return;
+ LOGP(DLLAPD, LOGL_INFO, "stop T200\n");
+ osmo_timer_del(&dl->t200);
+}
+
+static void lapd_stop_t203(struct lapd_datalink *dl)
+{
+ if (!osmo_timer_pending(&dl->t203))
+ return;
+ LOGP(DLLAPD, LOGL_INFO, "stop T203\n");
+ osmo_timer_del(&dl->t203);
+}
+
+static void lapd_dl_newstate(struct lapd_datalink *dl, uint32_t state)
+{
+ LOGP(DLLAPD, LOGL_INFO, "new state %s -> %s\n",
+ lapd_state_names[dl->state], lapd_state_names[state]);
+
+ if (state != LAPD_STATE_MF_EST && dl->state == LAPD_STATE_MF_EST) {
+ /* stop T203 on leaving MF EST state, if running */
+ lapd_stop_t203(dl);
+ /* remove content res. (network side) on leaving MF EST state */
+ if (dl->cont_res) {
+ msgb_free(dl->cont_res);
+ dl->cont_res = NULL;
+ }
+ }
+
+ /* start T203 on entering MF EST state, if enabled */
+ if ((dl->t203_sec || dl->t203_usec)
+ && state == LAPD_STATE_MF_EST && dl->state != LAPD_STATE_MF_EST)
+ lapd_start_t203(dl);
+
+ dl->state = state;
+}
+
+static void *tall_lapd_ctx = NULL;
+
+/* init datalink instance and allocate history */
+void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
+ int maxf)
+{
+ int m;
+
+ memset(dl, 0, sizeof(*dl));
+ INIT_LLIST_HEAD(&dl->send_queue);
+ INIT_LLIST_HEAD(&dl->tx_queue);
+ dl->reestablish = 1;
+ dl->n200_est_rel = 3;
+ dl->n200 = 3;
+ dl->t200_sec = 1;
+ dl->t200_usec = 0;
+ dl->t200.data = dl;
+ dl->t200.cb = &lapd_t200_cb;
+ dl->t203_sec = 10;
+ dl->t203_usec = 0;
+ dl->t203.data = dl;
+ dl->t203.cb = &lapd_t203_cb;
+ dl->maxf = maxf;
+ if (k > v_range - 1)
+ k = v_range - 1;
+ dl->k = k;
+ dl->v_range = v_range;
+
+ /* Calculate modulo for history array:
+ * - The history range must be at least k+1.
+ * - The history range must be 2^x, where x is as low as possible.
+ */
+ k++;
+ for (m = 0x80; m; m >>= 1) {
+ if ((m & k)) {
+ if (k > m)
+ m <<= 1;
+ dl->range_hist = m;
+ break;
+ }
+ }
+
+ LOGP(DLLAPD, LOGL_INFO, "Init DL layer: sequence range = %d, k = %d, "
+ "history range = %d\n", dl->v_range, dl->k, dl->range_hist);
+
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+
+ if (!tall_lapd_ctx)
+ tall_lapd_ctx = talloc_named_const(NULL, 1, "lapd context");
+ dl->tx_hist = (struct lapd_history *) talloc_zero_array(tall_lapd_ctx,
+ struct log_info, dl->range_hist);
+}
+
+/* reset to IDLE state */
+void lapd_dl_reset(struct lapd_datalink *dl)
+{
+ if (dl->state == LAPD_STATE_IDLE)
+ return;
+ LOGP(DLLAPD, LOGL_INFO, "Resetting LAPDm instance\n");
+ /* enter idle state (and remove eventual cont_res) */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ /* flush buffer */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ /* Discard partly received L3 message */
+ if (dl->rcv_buffer) {
+ msgb_free(dl->rcv_buffer);
+ dl->rcv_buffer = NULL;
+ }
+ /* stop Timers */
+ lapd_stop_t200(dl);
+ lapd_stop_t203(dl);
+}
+
+/* reset and de-allocate history buffer */
+void lapd_dl_exit(struct lapd_datalink *dl)
+{
+ /* free all ressources except history buffer */
+ lapd_dl_reset(dl);
+ /* free history buffer list */
+ talloc_free(dl->tx_hist);
+}
+
+/*! \brief Set the \ref lapdm_mode of a LAPDm entity */
+int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode)
+{
+ switch (mode) {
+ case LAPD_MODE_USER:
+ dl->cr.loc2rem.cmd = CR_USER2NET_CMD;
+ dl->cr.loc2rem.resp = CR_USER2NET_RESP;
+ dl->cr.rem2loc.cmd = CR_NET2USER_CMD;
+ dl->cr.rem2loc.resp = CR_NET2USER_RESP;
+ break;
+ case LAPD_MODE_NETWORK:
+ dl->cr.loc2rem.cmd = CR_NET2USER_CMD;
+ dl->cr.loc2rem.resp = CR_NET2USER_RESP;
+ dl->cr.rem2loc.cmd = CR_USER2NET_CMD;
+ dl->cr.rem2loc.resp = CR_USER2NET_RESP;
+ break;
+ default:
+ return -EINVAL;
+ }
+ dl->mode = mode;
+
+ return 0;
+}
+
+/* send DL message with optional msgb */
+static int send_dl_l3(uint8_t prim, uint8_t op, struct lapd_msg_ctx *lctx,
+ struct msgb *msg)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct osmo_dlsap_prim dp;
+
+ osmo_prim_init(&dp.oph, 0, prim, op, msg);
+ return dl->send_dlsap(&dp, lctx);
+}
+
+/* send simple DL message */
+static inline int send_dl_simple(uint8_t prim, uint8_t op,
+ struct lapd_msg_ctx *lctx)
+{
+ struct msgb *msg = lapd_msgb_alloc(0, "DUMMY");
+
+ return send_dl_l3(prim, op, lctx, msg);
+}
+
+/* send MDL-ERROR INDICATION */
+static int mdl_error(uint8_t cause, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct osmo_dlsap_prim dp;
+
+ LOGP(DLLAPD, LOGL_NOTICE, "sending MDL-ERROR-IND cause %d\n",
+ cause);
+ osmo_prim_init(&dp.oph, 0, PRIM_MDL_ERROR, PRIM_OP_INDICATION, NULL);
+ dp.u.error_ind.cause = cause;
+ return dl->send_dlsap(&dp, lctx);
+}
+
+/* send UA response */
+static int lapd_send_ua(struct lapd_msg_ctx *lctx, uint8_t len, uint8_t *data)
+{
+ struct msgb *msg = lapd_msgb_alloc(len, "LAPD UA");
+ struct lapd_msg_ctx nctx;
+ struct lapd_datalink *dl = lctx->dl;
+
+ memcpy(&nctx, lctx, sizeof(nctx));
+ msg->l3h = msgb_put(msg, len);
+ if (len)
+ memcpy(msg->l3h, data, len);
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.resp;
+ nctx.format = LAPD_FORM_U;
+ nctx.s_u = LAPD_U_UA;
+ /* keep nctx.p_f */
+ nctx.length = len;
+ nctx.more = 0;
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* send DM response */
+static int lapd_send_dm(struct lapd_msg_ctx *lctx)
+{
+ struct msgb *msg = lapd_msgb_alloc(0, "LAPD DM");
+ struct lapd_msg_ctx nctx;
+ struct lapd_datalink *dl = lctx->dl;
+
+ memcpy(&nctx, lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.resp;
+ nctx.format = LAPD_FORM_U;
+ nctx.s_u = LAPD_U_DM;
+ /* keep nctx.p_f */
+ nctx.length = 0;
+ nctx.more = 0;
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* send RR response / command */
+static int lapd_send_rr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
+{
+ struct msgb *msg = lapd_msgb_alloc(0, "LAPD RR");
+ struct lapd_msg_ctx nctx;
+ struct lapd_datalink *dl = lctx->dl;
+
+ memcpy(&nctx, lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
+ nctx.format = LAPD_FORM_S;
+ nctx.s_u = LAPD_S_RR;
+ nctx.p_f = f_bit;
+ nctx.n_recv = dl->v_recv;
+ nctx.length = 0;
+ nctx.more = 0;
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* send RNR response / command */
+static int lapd_send_rnr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
+{
+ struct msgb *msg = lapd_msgb_alloc(0, "LAPD RNR");
+ struct lapd_msg_ctx nctx;
+ struct lapd_datalink *dl = lctx->dl;
+
+ memcpy(&nctx, lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
+ nctx.format = LAPD_FORM_S;
+ nctx.s_u = LAPD_S_RNR;
+ nctx.p_f = f_bit;
+ nctx.n_recv = dl->v_recv;
+ nctx.length = 0;
+ nctx.more = 0;
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* send REJ response */
+static int lapd_send_rej(struct lapd_msg_ctx *lctx, uint8_t f_bit)
+{
+ struct msgb *msg = lapd_msgb_alloc(0, "LAPD REJ");
+ struct lapd_msg_ctx nctx;
+ struct lapd_datalink *dl = lctx->dl;
+
+ memcpy(&nctx, lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.resp;
+ nctx.format = LAPD_FORM_S;
+ nctx.s_u = LAPD_S_REJ;
+ nctx.p_f = f_bit;
+ nctx.n_recv = dl->v_recv;
+ nctx.length = 0;
+ nctx.more = 0;
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* resend SABM or DISC message */
+static int lapd_send_resend(struct lapd_datalink *dl)
+{
+ struct msgb *msg;
+ uint8_t h = do_mod(dl->v_send, dl->range_hist);
+ int length = dl->tx_hist[h].msg->len;
+ struct lapd_msg_ctx nctx;
+
+ /* assemble message */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_U;
+ if (dl->state == LAPD_STATE_SABM_SENT)
+ nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
+ else
+ nctx.s_u = LAPD_U_DISC;
+ nctx.p_f = 1;
+ nctx.length = length;
+ nctx.more = 0;
+
+ /* Resend SABM/DISC from tx_hist */
+ msg = lapd_msgb_alloc(length, "LAPD resend");
+ msg->l3h = msgb_put(msg, length);
+ if (length)
+ memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* reestablish link */
+static int lapd_reestablish(struct lapd_datalink *dl)
+{
+ struct osmo_dlsap_prim dp;
+ struct msgb *msg;
+
+ msg = lapd_msgb_alloc(0, "DUMMY");
+ osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
+
+ return lapd_est_req(&dp, &dl->lctx);
+}
+
+/* Timer callback on T200 expiry */
+static void lapd_t200_cb(void *data)
+{
+ struct lapd_datalink *dl = data;
+
+ LOGP(DLLAPD, LOGL_INFO, "Timeout T200 (%p) state=%d\n", dl,
+ (int) dl->state);
+
+ switch (dl->state) {
+ case LAPD_STATE_SABM_SENT:
+ /* 5.4.1.3 */
+ if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
+ /* send RELEASE INDICATION to L3 */
+ send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
+ &dl->lctx);
+ /* send MDL ERROR INIDCATION to L3 */
+ mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
+ /* flush tx and send buffers */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ /* go back to idle state */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ /* NOTE: we must not change any other states or buffers
+ * and queues, since we may reconnect after handover
+ * failure. the buffered messages is replaced there */
+ break;
+ }
+ /* retransmit SABM command */
+ lapd_send_resend(dl);
+ /* increment re-transmission counter */
+ dl->retrans_ctr++;
+ /* restart T200 (PH-READY-TO-SEND) */
+ lapd_start_t200(dl);
+ break;
+ case LAPD_STATE_DISC_SENT:
+ /* 5.4.4.3 */
+ if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
+ /* send RELEASE INDICATION to L3 */
+ send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
+ /* send MDL ERROR INIDCATION to L3 */
+ mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
+ /* flush tx and send buffers */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ /* go back to idle state */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ /* NOTE: we must not change any other states or buffers
+ * and queues, since we may reconnect after handover
+ * failure. the buffered messages is replaced there */
+ break;
+ }
+ /* retransmit DISC command */
+ lapd_send_resend(dl);
+ /* increment re-transmission counter */
+ dl->retrans_ctr++;
+ /* restart T200 (PH-READY-TO-SEND) */
+ lapd_start_t200(dl);
+ break;
+ case LAPD_STATE_MF_EST:
+ /* 5.5.7 */
+ dl->retrans_ctr = 0;
+ lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
+ /* fall through */
+ case LAPD_STATE_TIMER_RECOV:
+ dl->retrans_ctr++;
+ if (dl->retrans_ctr < dl->n200) {
+ uint8_t vs = sub_mod(dl->v_send, 1, dl->v_range);
+ uint8_t h = do_mod(vs, dl->range_hist);
+ /* retransmit I frame (V_s-1) with P=1, if any */
+ if (dl->tx_hist[h].msg) {
+ struct msgb *msg;
+ int length = dl->tx_hist[h].msg->len;
+ struct lapd_msg_ctx nctx;
+
+ LOGP(DLLAPD, LOGL_INFO, "retransmit last frame"
+ " V(S)=%d\n", vs);
+ /* Create I frame (segment) from tx_hist */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_I;
+ nctx.p_f = 1;
+ nctx.n_send = vs;
+ nctx.n_recv = dl->v_recv;
+ nctx.length = length;
+ nctx.more = dl->tx_hist[h].more;
+ msg = lapd_msgb_alloc(length, "LAPD I resend");
+ msg->l3h = msgb_put(msg, length);
+ memcpy(msg->l3h, dl->tx_hist[h].msg->data,
+ length);
+ dl->send_ph_data_req(&nctx, msg);
+ } else {
+ /* OR send appropriate supervision frame with P=1 */
+ if (!dl->own_busy && !dl->seq_err_cond) {
+ lapd_send_rr(&dl->lctx, 1, 1);
+ /* NOTE: In case of sequence error
+ * condition, the REJ frame has been
+ * transmitted when entering the
+ * condition, so it has not be done
+ * here
+ */
+ } else if (dl->own_busy) {
+ lapd_send_rnr(&dl->lctx, 1, 1);
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "unhandled, "
+ "pls. fix\n");
+ }
+ }
+ /* restart T200 (PH-READY-TO-SEND) */
+ lapd_start_t200(dl);
+ } else {
+ /* send MDL ERROR INIDCATION to L3 */
+ mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
+ /* reestablish */
+ if (!dl->reestablish)
+ break;
+ LOGP(DLLAPD, LOGL_NOTICE, "N200 reached, performing "
+ "reestablishment.\n");
+ lapd_reestablish(dl);
+ }
+ break;
+ default:
+ LOGP(DLLAPD, LOGL_INFO, "T200 expired in unexpected "
+ "dl->state %d\n", (int) dl->state);
+ }
+}
+
+/* Timer callback on T203 expiry */
+static void lapd_t203_cb(void *data)
+{
+ struct lapd_datalink *dl = data;
+
+ LOGP(DLLAPD, LOGL_INFO, "Timeout T203 (%p) state=%d\n", dl,
+ (int) dl->state);
+
+ if (dl->state != LAPD_STATE_MF_EST) {
+ LOGP(DLLAPD, LOGL_ERROR, "T203 fired outside MF EST state, "
+ "please fix!\n");
+ return;
+ }
+
+ /* set retransmission counter to 0 */
+ dl->retrans_ctr = 0;
+ /* enter timer recovery state */
+ lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
+ /* transmit a supervisory command with P bit set to 1 as follows: */
+ if (!dl->own_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "transmit an RR poll command\n");
+ /* Send RR with P=1 */
+ lapd_send_rr(&dl->lctx, 1, 1);
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "transmit an RNR poll command\n");
+ /* Send RNR with P=1 */
+ lapd_send_rnr(&dl->lctx, 1, 1);
+ }
+ /* start T200 */
+ lapd_start_t200(dl);
+}
+
+/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
+static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ uint8_t nr = lctx->n_recv;
+ int s = 0, rej = 0, t200_reset = 0, t200_start = 0;
+ int i, h;
+
+ /* supervisory frame ? */
+ if (lctx->format == LAPD_FORM_S)
+ s = 1;
+ /* REJ frame ? */
+ if (s && lctx->s_u == LAPD_S_REJ)
+ rej = 1;
+
+ /* Flush all transmit buffers of acknowledged frames */
+ for (i = dl->v_ack; i != nr; i = inc_mod(i, dl->v_range)) {
+ h = do_mod(i, dl->range_hist);
+ if (dl->tx_hist[h].msg) {
+ msgb_free(dl->tx_hist[h].msg);
+ dl->tx_hist[h].msg = NULL;
+ LOGP(DLLAPD, LOGL_INFO, "ack frame %d\n", i);
+ }
+ }
+
+ if (dl->state != LAPD_STATE_TIMER_RECOV) {
+ /* When not in the timer recovery condition, the data
+ * link layer entity shall reset the timer T200 on
+ * receipt of a valid I frame with N(R) higher than V(A),
+ * or an REJ with an N(R) equal to V(A). */
+ if ((!rej && nr != dl->v_ack)
+ || (rej && nr == dl->v_ack)) {
+ t200_reset = 1;
+ lapd_stop_t200(dl);
+ /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
+ }
+ /* 5.7.4: N(R) sequence error
+ * N(R) is called valid, if and only if
+ * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
+ */
+ if (sub_mod(nr, dl->v_ack, dl->v_range)
+ > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
+ LOGP(DLLAPD, LOGL_NOTICE, "N(R) sequence error\n");
+ mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
+ }
+ }
+
+ /* V(A) shall be set to the value of N(R) */
+ dl->v_ack = nr;
+
+ /* If T200 has been stopped by the receipt of an I, RR or RNR frame,
+ * and if there are outstanding I frames, restart T200 */
+ if (t200_reset && !rej) {
+ if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) {
+ LOGP(DLLAPD, LOGL_INFO, "start T200, due to unacked I "
+ "frame(s)\n");
+ t200_start = 1;
+ lapd_start_t200(dl);
+ }
+ }
+
+ /* This also does a restart, when I or S frame is received */
+
+ /* Stop T203, if running */
+ lapd_stop_t203(dl);
+ /* Start T203, if T200 is not running in MF EST state, if enabled */
+ if (!osmo_timer_pending(&dl->t200)
+ && (dl->t203_sec || dl->t203_usec)
+ && (dl->state == LAPD_STATE_MF_EST)) {
+ lapd_start_t203(dl);
+ }
+}
+
+/* L1 -> L2 */
+
+/* Receive a LAPD U (Unnumbered) message from L1 */
+static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ int length = lctx->length;
+ int rc = 0;
+ uint8_t prim, op;
+
+ switch (lctx->s_u) {
+ case LAPD_U_SABM:
+ case LAPD_U_SABME:
+ prim = PRIM_DL_EST;
+ op = PRIM_OP_INDICATION;
+
+ LOGP(DLLAPD, LOGL_INFO, "SABM(E) received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* 5.7.1 */
+ dl->seq_err_cond = 0;
+ /* G.2.2 Wrong value of the C/R bit */
+ if (lctx->cr == dl->cr.rem2loc.resp) {
+ LOGP(DLLAPD, LOGL_NOTICE, "SABM response error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+
+ /* G.4.5 If SABM is received with L>N201 or with M bit
+ * set, AN MDL-ERROR-INDICATION is sent to MM.
+ */
+ if (lctx->more || length > lctx->n201) {
+ LOGP(DLLAPD, LOGL_NOTICE, "SABM too large error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
+ return -EIO;
+ }
+
+ switch (dl->state) {
+ case LAPD_STATE_IDLE:
+ break;
+ case LAPD_STATE_MF_EST:
+ LOGP(DLLAPD, LOGL_INFO, "SABM command, multiple "
+ "frame established state\n");
+ /* If link is lost on the remote side, we start over
+ * and send DL-ESTABLISH indication again. */
+ if (dl->v_send != dl->v_recv) {
+ LOGP(DLLAPD, LOGL_INFO, "Remote reestablish\n");
+ mdl_error(MDL_CAUSE_SABM_MF, lctx);
+ break;
+ }
+ /* Ignore SABM if content differs from first SABM. */
+ if (dl->mode == LAPD_MODE_NETWORK && length
+ && dl->cont_res) {
+#ifdef TEST_CONTENT_RESOLUTION_NETWORK
+ dl->cont_res->data[0] ^= 0x01;
+#endif
+ if (memcmp(dl->cont_res, msg->data, length)) {
+ LOGP(DLLAPD, LOGL_INFO, "Another SABM "
+ "with diffrent content - "
+ "ignoring!\n");
+ msgb_free(msg);
+ return 0;
+ }
+ }
+ /* send UA again */
+ lapd_send_ua(lctx, length, msg->l3h);
+ msgb_free(msg);
+ return 0;
+ case LAPD_STATE_DISC_SENT:
+ /* 5.4.6.2 send DM with F=P */
+ lapd_send_dm(lctx);
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ msgb_free(msg);
+ return send_dl_simple(prim, op, lctx);
+ default:
+ /* collision: Send UA, but still wait for rx UA, then
+ * change to MF_EST state.
+ */
+ /* check for contention resoultion */
+ if (dl->tx_hist[0].msg && dl->tx_hist[0].msg->len) {
+ LOGP(DLLAPD, LOGL_NOTICE, "SABM not allowed "
+ "during contention resolution\n");
+ mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
+ }
+ lapd_send_ua(lctx, length, msg->l3h);
+ msgb_free(msg);
+ return 0;
+ }
+ /* save message context for further use */
+ memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
+#ifndef TEST_CONTENT_RESOLUTION_NETWORK
+ /* send UA response */
+ lapd_send_ua(lctx, length, msg->l3h);
+#endif
+ /* set Vs, Vr and Va to 0 */
+ dl->v_send = dl->v_recv = dl->v_ack = 0;
+ /* clear tx_hist */
+ lapd_dl_flush_hist(dl);
+ /* enter multiple-frame-established state */
+ lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
+ /* store content resolution data on network side
+ * Note: cont_res will be removed when changing state again,
+ * so it must be allocated AFTER lapd_dl_newstate(). */
+ if (dl->mode == LAPD_MODE_NETWORK && length) {
+ dl->cont_res = lapd_msgb_alloc(length, "CONT RES");
+ memcpy(msgb_put(dl->cont_res, length), msg->l3h,
+ length);
+ LOGP(DLLAPD, LOGL_NOTICE, "Store content res.\n");
+ }
+ /* send notification to L3 */
+ if (length == 0) {
+ /* 5.4.1.2 Normal establishment procedures */
+ rc = send_dl_simple(prim, op, lctx);
+ msgb_free(msg);
+ } else {
+ /* 5.4.1.4 Contention resolution establishment */
+ rc = send_dl_l3(prim, op, lctx, msg);
+ }
+ break;
+ case LAPD_U_DM:
+ LOGP(DLLAPD, LOGL_INFO, "DM received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* G.2.2 Wrong value of the C/R bit */
+ if (lctx->cr == dl->cr.rem2loc.cmd) {
+ LOGP(DLLAPD, LOGL_NOTICE, "DM command error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+ if (!lctx->p_f) {
+ /* 5.4.1.2 DM responses with the F bit set to "0"
+ * shall be ignored.
+ */
+ msgb_free(msg);
+ return 0;
+ }
+ switch (dl->state) {
+ case LAPD_STATE_SABM_SENT:
+ break;
+ case LAPD_STATE_MF_EST:
+ if (lctx->p_f) {
+ LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
+ "response\n");
+ mdl_error(MDL_CAUSE_UNSOL_DM_RESP, lctx);
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
+ "response, multiple frame established "
+ "state\n");
+ mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
+ /* reestablish */
+ if (!dl->reestablish) {
+ msgb_free(msg);
+ return 0;
+ }
+ LOGP(DLLAPD, LOGL_NOTICE, "Performing "
+ "reestablishment.\n");
+ lapd_reestablish(dl);
+ }
+ msgb_free(msg);
+ return 0;
+ case LAPD_STATE_TIMER_RECOV:
+ /* FP = 0 (DM is normal in case PF = 1) */
+ if (!lctx->p_f) {
+ LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
+ "response, multiple frame established "
+ "state\n");
+ mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
+ msgb_free(msg);
+ /* reestablish */
+ if (!dl->reestablish)
+ return 0;
+ LOGP(DLLAPD, LOGL_NOTICE, "Performing "
+ "reestablishment.\n");
+ return lapd_reestablish(dl);
+ }
+ break;
+ case LAPD_STATE_DISC_SENT:
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* go to idle state */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
+ msgb_free(msg);
+ return 0;
+ case LAPD_STATE_IDLE:
+ /* 5.4.5 all other frame types shall be discarded */
+ default:
+ LOGP(DLLAPD, LOGL_INFO, "unsolicited DM response! "
+ "(discarding)\n");
+ msgb_free(msg);
+ return 0;
+ }
+ /* stop timer T200 */
+ lapd_stop_t200(dl);
+ /* go to idle state */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
+ msgb_free(msg);
+ break;
+ case LAPD_U_UI:
+ LOGP(DLLAPD, LOGL_INFO, "UI received\n");
+ /* G.2.2 Wrong value of the C/R bit */
+ if (lctx->cr == dl->cr.rem2loc.resp) {
+ LOGP(DLLAPD, LOGL_NOTICE, "UI indicates response "
+ "error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+
+ /* G.4.5 If UI is received with L>N201 or with M bit
+ * set, AN MDL-ERROR-INDICATION is sent to MM.
+ */
+ if (length > lctx->n201 || lctx->more) {
+ LOGP(DLLAPD, LOGL_NOTICE, "UI too large error "
+ "(%d > N201(%d) or M=%d)\n", length,
+ lctx->n201, lctx->more);
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
+ return -EIO;
+ }
+
+ /* do some length checks */
+ if (length == 0) {
+ /* 5.3.3 UI frames received with the length indicator
+ * set to "0" shall be ignored
+ */
+ LOGP(DLLAPD, LOGL_INFO, "length=0 (discarding)\n");
+ msgb_free(msg);
+ return 0;
+ }
+ rc = send_dl_l3(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION, lctx,
+ msg);
+ break;
+ case LAPD_U_DISC:
+ prim = PRIM_DL_REL;
+ op = PRIM_OP_INDICATION;
+
+ LOGP(DLLAPD, LOGL_INFO, "DISC received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* flush tx and send buffers */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ /* 5.7.1 */
+ dl->seq_err_cond = 0;
+ /* G.2.2 Wrong value of the C/R bit */
+ if (lctx->cr == dl->cr.rem2loc.resp) {
+ LOGP(DLLAPD, LOGL_NOTICE, "DISC response error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+ if (length > 0 || lctx->more) {
+ /* G.4.4 If a DISC or DM frame is received with L>0 or
+ * with the M bit set to "1", an MDL-ERROR-INDICATION
+ * primitive with cause "U frame with incorrect
+ * parameters" is sent to the mobile management entity.
+ */
+ LOGP(DLLAPD, LOGL_NOTICE,
+ "U frame iwth incorrect parameters ");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
+ return -EIO;
+ }
+ switch (dl->state) {
+ case LAPD_STATE_IDLE:
+ LOGP(DLLAPD, LOGL_INFO, "DISC in idle state\n");
+ /* send DM with F=P */
+ msgb_free(msg);
+ return lapd_send_dm(lctx);
+ case LAPD_STATE_SABM_SENT:
+ LOGP(DLLAPD, LOGL_INFO, "DISC in SABM state\n");
+ /* 5.4.6.2 send DM with F=P */
+ lapd_send_dm(lctx);
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* go to idle state */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ msgb_free(msg);
+ return send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
+ lctx);
+ case LAPD_STATE_MF_EST:
+ case LAPD_STATE_TIMER_RECOV:
+ LOGP(DLLAPD, LOGL_INFO, "DISC in est state\n");
+ break;
+ case LAPD_STATE_DISC_SENT:
+ LOGP(DLLAPD, LOGL_INFO, "DISC in disc state\n");
+ prim = PRIM_DL_REL;
+ op = PRIM_OP_CONFIRM;
+ break;
+ default:
+ lapd_send_ua(lctx, length, msg->l3h);
+ msgb_free(msg);
+ return 0;
+ }
+ /* send UA response */
+ lapd_send_ua(lctx, length, msg->l3h);
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* enter idle state, keep tx-buffer with UA response */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ /* send notification to L3 */
+ rc = send_dl_simple(prim, op, lctx);
+ msgb_free(msg);
+ break;
+ case LAPD_U_UA:
+ LOGP(DLLAPD, LOGL_INFO, "UA received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* G.2.2 Wrong value of the C/R bit */
+ if (lctx->cr == dl->cr.rem2loc.cmd) {
+ LOGP(DLLAPD, LOGL_NOTICE, "UA indicates command "
+ "error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+
+ /* G.4.5 If UA is received with L>N201 or with M bit
+ * set, AN MDL-ERROR-INDICATION is sent to MM.
+ */
+ if (lctx->more || length > lctx->n201) {
+ LOGP(DLLAPD, LOGL_NOTICE, "UA too large error\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
+ return -EIO;
+ }
+
+ if (!lctx->p_f) {
+ /* 5.4.1.2 A UA response with the F bit set to "0"
+ * shall be ignored.
+ */
+ LOGP(DLLAPD, LOGL_INFO, "F=0 (discarding)\n");
+ msgb_free(msg);
+ return 0;
+ }
+ switch (dl->state) {
+ case LAPD_STATE_SABM_SENT:
+ break;
+ case LAPD_STATE_MF_EST:
+ case LAPD_STATE_TIMER_RECOV:
+ LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
+ "(discarding)\n");
+ mdl_error(MDL_CAUSE_UNSOL_UA_RESP, lctx);
+ msgb_free(msg);
+ return 0;
+ case LAPD_STATE_DISC_SENT:
+ LOGP(DLLAPD, LOGL_INFO, "UA in disconnect state\n");
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* go to idle state */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
+ msgb_free(msg);
+ return 0;
+ case LAPD_STATE_IDLE:
+ /* 5.4.5 all other frame types shall be discarded */
+ default:
+ LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
+ "(discarding)\n");
+ msgb_free(msg);
+ return 0;
+ }
+ LOGP(DLLAPD, LOGL_INFO, "UA in SABM state\n");
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* compare UA with SABME if contention resolution is applied */
+ if (dl->tx_hist[0].msg->len) {
+ if (length != (dl->tx_hist[0].msg->len)
+ || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h,
+ length)) {
+ LOGP(DLLAPD, LOGL_INFO, "**** UA response "
+ "mismatches ****\n");
+ rc = send_dl_simple(PRIM_DL_REL,
+ PRIM_OP_INDICATION, lctx);
+ msgb_free(msg);
+ /* go to idle state */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ return 0;
+ }
+ }
+ /* set Vs, Vr and Va to 0 */
+ dl->v_send = dl->v_recv = dl->v_ack = 0;
+ /* clear tx_hist */
+ lapd_dl_flush_hist(dl);
+ /* enter multiple-frame-established state */
+ lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
+ /* send outstanding frames, if any (resume / reconnect) */
+ lapd_send_i(lctx, __LINE__);
+ /* send notification to L3 */
+ rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
+ msgb_free(msg);
+ break;
+ case LAPD_U_FRMR:
+ LOGP(DLLAPD, LOGL_NOTICE, "Frame reject received\n");
+ /* send MDL ERROR INIDCATION to L3 */
+ mdl_error(MDL_CAUSE_FRMR, lctx);
+ msgb_free(msg);
+ /* reestablish */
+ if (!dl->reestablish)
+ break;
+ LOGP(DLLAPD, LOGL_NOTICE, "Performing reestablishment.\n");
+ rc = lapd_reestablish(dl);
+ break;
+ default:
+ /* G.3.1 */
+ LOGP(DLLAPD, LOGL_NOTICE, "Unnumbered frame not allowed.\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+ return rc;
+}
+
+/* Receive a LAPD S (Supervisory) message from L1 */
+static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ int length = lctx->length;
+
+ if (length > 0 || lctx->more) {
+ /* G.4.3 If a supervisory frame is received with L>0 or
+ * with the M bit set to "1", an MDL-ERROR-INDICATION
+ * primitive with cause "S frame with incorrect
+ * parameters" is sent to the mobile management entity. */
+ LOGP(DLLAPD, LOGL_NOTICE,
+ "S frame with incorrect parameters\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
+ return -EIO;
+ }
+
+ if (lctx->cr == dl->cr.rem2loc.resp
+ && lctx->p_f
+ && dl->state != LAPD_STATE_TIMER_RECOV) {
+ /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
+ LOGP(DLLAPD, LOGL_NOTICE, "S frame response with F=1 error\n");
+ mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
+ }
+
+ switch (dl->state) {
+ case LAPD_STATE_IDLE:
+ /* if P=1, respond DM with F=1 (5.2.2) */
+ /* 5.4.5 all other frame types shall be discarded */
+ if (lctx->p_f)
+ lapd_send_dm(lctx); /* F=P */
+ /* fall though */
+ case LAPD_STATE_SABM_SENT:
+ case LAPD_STATE_DISC_SENT:
+ LOGP(DLLAPD, LOGL_NOTICE, "S frame ignored in this state\n");
+ msgb_free(msg);
+ return 0;
+ }
+ switch (lctx->s_u) {
+ case LAPD_S_RR:
+ LOGP(DLLAPD, LOGL_INFO, "RR received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
+ lapd_acknowledge(lctx);
+
+ /* 5.5.3.2 */
+ if (lctx->cr == dl->cr.rem2loc.cmd
+ && lctx->p_f) {
+ if (!dl->own_busy && !dl->seq_err_cond) {
+ LOGP(DLLAPD, LOGL_INFO, "RR frame command "
+ "with polling bit set and we are not "
+ "busy, so we reply with RR frame "
+ "response\n");
+ lapd_send_rr(lctx, 1, 0);
+ /* NOTE: In case of sequence error condition,
+ * the REJ frame has been transmitted when
+ * entering the condition, so it has not be
+ * done here
+ */
+ } else if (dl->own_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "RR frame command "
+ "with polling bit set and we are busy, "
+ "so we reply with RR frame response\n");
+ lapd_send_rnr(lctx, 1, 0);
+ }
+ } else if (lctx->cr == dl->cr.rem2loc.resp
+ && lctx->p_f
+ && dl->state == LAPD_STATE_TIMER_RECOV) {
+ LOGP(DLLAPD, LOGL_INFO, "RR response with F==1, "
+ "and we are in timer recovery state, so "
+ "we leave that state\n");
+ /* V(S) to the N(R) in the RR frame */
+ dl->v_send = lctx->n_recv;
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* 5.5.7 Clear timer recovery condition */
+ lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
+ }
+ /* Send message, if possible due to acknowledged data */
+ lapd_send_i(lctx, __LINE__);
+
+ break;
+ case LAPD_S_RNR:
+ LOGP(DLLAPD, LOGL_INFO, "RNR received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
+ lapd_acknowledge(lctx);
+
+ /* 5.5.5 */
+ /* Set peer receiver busy condition */
+ dl->peer_busy = 1;
+
+ if (lctx->p_f) {
+ if (lctx->cr == dl->cr.rem2loc.cmd) {
+ if (!dl->own_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "RNR poll "
+ "command and we are not busy, "
+ "so we reply with RR final "
+ "response\n");
+ /* Send RR with F=1 */
+ lapd_send_rr(lctx, 1, 0);
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "RNR poll "
+ "command and we are busy, so "
+ "we reply with RNR final "
+ "response\n");
+ /* Send RNR with F=1 */
+ lapd_send_rnr(lctx, 1, 0);
+ }
+ } else if (dl->state == LAPD_STATE_TIMER_RECOV) {
+ LOGP(DLLAPD, LOGL_INFO, "RNR poll response "
+ "and we in timer recovery state, so "
+ "we leave that state\n");
+ /* 5.5.7 Clear timer recovery condition */
+ lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
+ /* V(S) to the N(R) in the RNR frame */
+ dl->v_send = lctx->n_recv;
+ }
+ } else
+ LOGP(DLLAPD, LOGL_INFO, "RNR not polling/final state "
+ "received\n");
+
+ /* Send message, if possible due to acknowledged data */
+ lapd_send_i(lctx, __LINE__);
+
+ break;
+ case LAPD_S_REJ:
+ LOGP(DLLAPD, LOGL_INFO, "REJ received in state %s\n",
+ lapd_state_names[dl->state]);
+ /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
+ lapd_acknowledge(lctx);
+
+ /* 5.5.4.1 */
+ if (dl->state != LAPD_STATE_TIMER_RECOV) {
+ /* Clear an existing peer receiver busy condition */
+ dl->peer_busy = 0;
+ /* V(S) and V(A) to the N(R) in the REJ frame */
+ dl->v_send = dl->v_ack = lctx->n_recv;
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* 5.5.3.2 */
+ if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
+ if (!dl->own_busy && !dl->seq_err_cond) {
+ LOGP(DLLAPD, LOGL_INFO, "REJ poll "
+ "command not in timer recovery "
+ "state and not in own busy "
+ "condition received, so we "
+ "respond with RR final "
+ "response\n");
+ lapd_send_rr(lctx, 1, 0);
+ /* NOTE: In case of sequence error
+ * condition, the REJ frame has been
+ * transmitted when entering the
+ * condition, so it has not be done
+ * here
+ */
+ } else if (dl->own_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "REJ poll "
+ "command not in timer recovery "
+ "state and in own busy "
+ "condition received, so we "
+ "respond with RNR final "
+ "response\n");
+ lapd_send_rnr(lctx, 1, 0);
+ }
+ } else
+ LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
+ "polling command not in timer recovery "
+ "state received\n");
+ /* send MDL ERROR INIDCATION to L3 */
+ if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
+ mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
+ }
+
+ } else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
+ LOGP(DLLAPD, LOGL_INFO, "REJ poll response in timer "
+ "recovery state received\n");
+ /* Clear an existing peer receiver busy condition */
+ dl->peer_busy = 0;
+ /* V(S) and V(A) to the N(R) in the REJ frame */
+ dl->v_send = dl->v_ack = lctx->n_recv;
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* 5.5.7 Clear timer recovery condition */
+ lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
+ } else {
+ /* Clear an existing peer receiver busy condition */
+ dl->peer_busy = 0;
+ /* V(S) and V(A) to the N(R) in the REJ frame */
+ dl->v_send = dl->v_ack = lctx->n_recv;
+ /* 5.5.3.2 */
+ if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
+ if (!dl->own_busy && !dl->seq_err_cond) {
+ LOGP(DLLAPD, LOGL_INFO, "REJ poll "
+ "command in timer recovery "
+ "state and not in own busy "
+ "condition received, so we "
+ "respond with RR final "
+ "response\n");
+ lapd_send_rr(lctx, 1, 0);
+ /* NOTE: In case of sequence error
+ * condition, the REJ frame has been
+ * transmitted when entering the
+ * condition, so it has not be done
+ * here
+ */
+ } else if (dl->own_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "REJ poll "
+ "command in timer recovery "
+ "state and in own busy "
+ "condition received, so we "
+ "respond with RNR final "
+ "response\n");
+ lapd_send_rnr(lctx, 1, 0);
+ }
+ } else
+ LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
+ "polling command in timer recovery "
+ "state received\n");
+ }
+
+ /* FIXME: 5.5.4.2 2) */
+
+ /* Send message, if possible due to acknowledged data */
+ lapd_send_i(lctx, __LINE__);
+
+ break;
+ default:
+ /* G.3.1 */
+ LOGP(DLLAPD, LOGL_NOTICE, "Supervisory frame not allowed.\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+ msgb_free(msg);
+ return 0;
+}
+
+/* Receive a LAPD I (Information) message from L1 */
+static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ //uint8_t nr = lctx->n_recv;
+ uint8_t ns = lctx->n_send;
+ int length = lctx->length;
+ int rc;
+
+ LOGP(DLLAPD, LOGL_INFO, "I received in state %s\n",
+ lapd_state_names[dl->state]);
+
+ /* G.2.2 Wrong value of the C/R bit */
+ if (lctx->cr == dl->cr.rem2loc.resp) {
+ LOGP(DLLAPD, LOGL_NOTICE, "I frame response not allowed\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
+ return -EINVAL;
+ }
+
+ if (length == 0 || length > lctx->n201) {
+ /* G.4.2 If the length indicator of an I frame is set
+ * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
+ * primitive with cause "I frame with incorrect length"
+ * is sent to the mobile management entity. */
+ LOGP(DLLAPD, LOGL_NOTICE, "I frame length not allowed\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
+ return -EIO;
+ }
+
+ /* G.4.2 If the numerical value of L is L<N201 and the M
+ * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
+ * cause "I frame with incorrect use of M bit" is sent to the
+ * mobile management entity. */
+ if (lctx->more && length < lctx->n201) {
+ LOGP(DLLAPD, LOGL_NOTICE, "I frame with M bit too short\n");
+ msgb_free(msg);
+ mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
+ return -EIO;
+ }
+
+ switch (dl->state) {
+ case LAPD_STATE_IDLE:
+ /* if P=1, respond DM with F=1 (5.2.2) */
+ /* 5.4.5 all other frame types shall be discarded */
+ if (lctx->p_f)
+ lapd_send_dm(lctx); /* F=P */
+ /* fall though */
+ case LAPD_STATE_SABM_SENT:
+ case LAPD_STATE_DISC_SENT:
+ LOGP(DLLAPD, LOGL_NOTICE, "I frame ignored in this state\n");
+ msgb_free(msg);
+ return 0;
+ }
+
+ /* 5.7.1: N(s) sequence error */
+ if (ns != dl->v_recv) {
+ LOGP(DLLAPD, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
+ "V(R)=%u\n", ns, dl->v_recv);
+ /* discard data */
+ msgb_free(msg);
+ if (dl->seq_err_cond != 1) {
+ /* FIXME: help me understand what exactly todo here
+ */
+ dl->seq_err_cond = 1;
+ lapd_send_rej(lctx, lctx->p_f);
+ } else {
+ /* If there are two subsequent sequence errors received,
+ * ignore it. (Ignore every second subsequent error.)
+ * This happens if our reply with the REJ is too slow,
+ * so the remote gets a T200 timeout and sends another
+ * frame with a sequence error.
+ * Test showed that replying with two subsequent REJ
+ * messages could the remote L2 process to abort.
+ * Replying too slow shouldn't happen, but may happen
+ * over serial link between BB and LAPD.
+ */
+ dl->seq_err_cond = 2;
+ }
+ /* Even if N(s) sequence error, acknowledge to N(R)-1 */
+ /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
+ lapd_acknowledge(lctx); /* V(A) is also set here */
+
+ /* Send message, if possible due to acknowledged data */
+ lapd_send_i(lctx, __LINE__);
+
+ return 0;
+ }
+ dl->seq_err_cond = 0;
+
+ /* Increment receiver state */
+ dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
+ LOGP(DLLAPD, LOGL_INFO, "incrementing V(R) to %u\n", dl->v_recv);
+
+ /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
+ lapd_acknowledge(lctx); /* V(A) is also set here */
+
+ /* Only if we are not in own receiver busy condition */
+ if (!dl->own_busy) {
+ /* if the frame carries a complete segment */
+ if (!lctx->more && !dl->rcv_buffer) {
+ LOGP(DLLAPD, LOGL_INFO, "message in single I frame\n");
+ /* send a DATA INDICATION to L3 */
+ msg->len = length;
+ msg->tail = msg->data + length;
+ rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
+ msg);
+ } else {
+ /* create rcv_buffer */
+ if (!dl->rcv_buffer) {
+ LOGP(DLLAPD, LOGL_INFO, "message in multiple "
+ "I frames (first message)\n");
+ dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
+ "LAPD RX");
+ dl->rcv_buffer->l3h = dl->rcv_buffer->data;
+ }
+ /* concat. rcv_buffer */
+ if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
+ LOGP(DLLAPD, LOGL_NOTICE, "Received frame "
+ "overflow!\n");
+ } else {
+ memcpy(msgb_put(dl->rcv_buffer, length),
+ msg->l3h, length);
+ }
+ /* if the last segment was received */
+ if (!lctx->more) {
+ LOGP(DLLAPD, LOGL_INFO, "message in multiple "
+ "I frames (last message)\n");
+ rc = send_dl_l3(PRIM_DL_DATA,
+ PRIM_OP_INDICATION, lctx,
+ dl->rcv_buffer);
+ dl->rcv_buffer = NULL;
+ } else
+ LOGP(DLLAPD, LOGL_INFO, "message in multiple "
+ "I frames (next message)\n");
+ msgb_free(msg);
+
+ }
+ } else
+ LOGP(DLLAPD, LOGL_INFO, "I frame ignored during own receiver "
+ "busy condition\n");
+
+ /* Check for P bit */
+ if (lctx->p_f) {
+ /* 5.5.2.1 */
+ /* check if we are not in own receiver busy */
+ if (!dl->own_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "we are not busy, send RR\n");
+ /* Send RR with F=1 */
+ rc = lapd_send_rr(lctx, 1, 0);
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "we are busy, send RNR\n");
+ /* Send RNR with F=1 */
+ rc = lapd_send_rnr(lctx, 1, 0);
+ }
+ } else {
+ /* 5.5.2.2 */
+ /* check if we are not in own receiver busy */
+ if (!dl->own_busy) {
+ /* NOTE: V(R) is already set above */
+ rc = lapd_send_i(lctx, __LINE__);
+ if (rc) {
+ LOGP(DLLAPD, LOGL_INFO, "we are not busy and "
+ "have no pending data, send RR\n");
+ /* Send RR with F=0 */
+ return lapd_send_rr(lctx, 0, 0);
+ }
+ /* all I or one RR is sent, we are done */
+ return 0;
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "we are busy, send RNR\n");
+ /* Send RNR with F=0 */
+ rc = lapd_send_rnr(lctx, 0, 0);
+ }
+ }
+
+ /* Send message, if possible due to acknowledged data */
+ lapd_send_i(lctx, __LINE__);
+
+ return rc;
+}
+
+/* Receive a LAPD message from L1 */
+int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
+{
+ int rc;
+
+ switch (lctx->format) {
+ case LAPD_FORM_U:
+ rc = lapd_rx_u(msg, lctx);
+ break;
+ case LAPD_FORM_S:
+ rc = lapd_rx_s(msg, lctx);
+ break;
+ case LAPD_FORM_I:
+ rc = lapd_rx_i(msg, lctx);
+ break;
+ default:
+ LOGP(DLLAPD, LOGL_NOTICE, "unknown LAPD format\n");
+ msgb_free(msg);
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+/* L3 -> L2 */
+
+/* send unit data */
+static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+ struct lapd_msg_ctx nctx;
+
+ memcpy(&nctx, lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_U;
+ nctx.s_u = LAPD_U_UI;
+ /* keep nctx.p_f */
+ nctx.length = msg->len;
+ nctx.more = 0;
+
+ return dl->send_ph_data_req(&nctx, msg);
+}
+
+/* request link establishment */
+static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+ struct lapd_msg_ctx nctx;
+
+ if (msg->len)
+ LOGP(DLLAPD, LOGL_INFO, "perform establishment with content "
+ "(SABM)\n");
+ else
+ LOGP(DLLAPD, LOGL_INFO, "perform normal establishm. (SABM)\n");
+
+ /* Flush send-queue */
+ /* Clear send-buffer */
+ lapd_dl_flush_send(dl);
+ /* be sure that history is empty */
+ lapd_dl_flush_hist(dl);
+
+ /* save message context for further use */
+ memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
+
+ /* Discard partly received L3 message */
+ if (dl->rcv_buffer) {
+ msgb_free(dl->rcv_buffer);
+ dl->rcv_buffer = NULL;
+ }
+
+ /* assemble message */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_U;
+ nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
+ nctx.p_f = 1;
+ nctx.length = msg->len;
+ nctx.more = 0;
+
+ /* Transmit-buffer carries exactly one segment */
+ dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
+ msgb_put(dl->tx_hist[0].msg, msg->len);
+ if (msg->len)
+ memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
+ dl->tx_hist[0].more = 0;
+ /* set Vs to 0, because it is used as index when resending SABM */
+ dl->v_send = 0;
+
+ /* Set states */
+ dl->own_busy = dl->peer_busy = 0;
+ dl->retrans_ctr = 0;
+ lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
+
+ /* Tramsmit and start T200 */
+ dl->send_ph_data_req(&nctx, msg);
+ lapd_start_t200(dl);
+
+ return 0;
+}
+
+/* send data */
+static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+
+ if (msgb_l3len(msg) == 0) {
+ LOGP(DLLAPD, LOGL_ERROR,
+ "writing an empty message is not possible.\n");
+ msgb_free(msg);
+ return -1;
+ }
+
+ LOGP(DLLAPD, LOGL_INFO,
+ "writing message to send-queue: l3len: %d\n", msgb_l3len(msg));
+
+ /* Write data into the send queue */
+ msgb_enqueue(&dl->send_queue, msg);
+
+ /* Send message, if possible */
+ lapd_send_i(&dl->lctx, __LINE__);
+
+ return 0;
+}
+
+/* Send next I frame from queued/buffered data */
+static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ uint8_t k = dl->k;
+ uint8_t h;
+ struct msgb *msg;
+ int length, left;
+ int rc = - 1; /* we sent nothing */
+ struct lapd_msg_ctx nctx;
+
+
+ LOGP(DLLAPD, LOGL_INFO, "%s() called from line %d\n", __func__, line);
+
+ next_frame:
+
+ if (dl->peer_busy) {
+ LOGP(DLLAPD, LOGL_INFO, "peer busy, not sending\n");
+ return rc;
+ }
+
+ if (dl->state == LAPD_STATE_TIMER_RECOV) {
+ LOGP(DLLAPD, LOGL_INFO, "timer recovery, not sending\n");
+ return rc;
+ }
+
+ /* If the send state variable V(S) is equal to V(A) plus k
+ * (where k is the maximum number of outstanding I frames - see
+ * subclause 5.8.4), the data link layer entity shall not transmit any
+ * new I frames, but shall retransmit an I frame as a result
+ * of the error recovery procedures as described in subclauses 5.5.4 and
+ * 5.5.7. */
+ if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
+ LOGP(DLLAPD, LOGL_INFO, "k frames outstanding, not sending "
+ "more (k=%u V(S)=%u V(A)=%u)\n", k, dl->v_send,
+ dl->v_ack);
+ return rc;
+ }
+
+ h = do_mod(dl->v_send, dl->range_hist);
+
+ /* if we have no tx_hist yet, we create it */
+ if (!dl->tx_hist[h].msg) {
+ /* Get next message into send-buffer, if any */
+ if (!dl->send_buffer) {
+ next_message:
+ dl->send_out = 0;
+ dl->send_buffer = msgb_dequeue(&dl->send_queue);
+ /* No more data to be sent */
+ if (!dl->send_buffer)
+ return rc;
+ LOGP(DLLAPD, LOGL_INFO, "get message from "
+ "send-queue\n");
+ }
+
+ /* How much is left in the send-buffer? */
+ left = msgb_l3len(dl->send_buffer) - dl->send_out;
+ /* Segment, if data exceeds N201 */
+ length = left;
+ if (length > lctx->n201)
+ length = lctx->n201;
+ LOGP(DLLAPD, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
+ "length %d first byte %02x\n",
+ msgb_l3len(dl->send_buffer), dl->send_out, left,
+ lctx->n201, length, dl->send_buffer->l3h[0]);
+ /* If message in send-buffer is completely sent */
+ if (left == 0) {
+ msgb_free(dl->send_buffer);
+ dl->send_buffer = NULL;
+ goto next_message;
+ }
+
+ LOGP(DLLAPD, LOGL_INFO, "send I frame %sV(S)=%d\n",
+ (left > length) ? "segment " : "", dl->v_send);
+
+ /* Create I frame (segment) and transmit-buffer content */
+ msg = lapd_msgb_alloc(length, "LAPD I");
+ msg->l3h = msgb_put(msg, length);
+ /* assemble message */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_I;
+ nctx.p_f = 0;
+ nctx.n_send = dl->v_send;
+ nctx.n_recv = dl->v_recv;
+ nctx.length = length;
+ if (left > length)
+ nctx.more = 1;
+ else
+ nctx.more = 0;
+ if (length)
+ memcpy(msg->l3h, dl->send_buffer->l3h + dl->send_out,
+ length);
+ /* store in tx_hist */
+ dl->tx_hist[h].msg = lapd_msgb_alloc(msg->len, "HIST");
+ msgb_put(dl->tx_hist[h].msg, msg->len);
+ if (length)
+ memcpy(dl->tx_hist[h].msg->data, msg->l3h, msg->len);
+ dl->tx_hist[h].more = nctx.more;
+ /* Add length to track how much is already in the tx buffer */
+ dl->send_out += length;
+ } else {
+ LOGP(DLLAPD, LOGL_INFO, "resend I frame from tx buffer "
+ "V(S)=%d\n", dl->v_send);
+
+ /* Create I frame (segment) from tx_hist */
+ length = dl->tx_hist[h].msg->len;
+ msg = lapd_msgb_alloc(length, "LAPD I resend");
+ msg->l3h = msgb_put(msg, length);
+ /* assemble message */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_I;
+ nctx.p_f = 0;
+ nctx.n_send = dl->v_send;
+ nctx.n_recv = dl->v_recv;
+ nctx.length = length;
+ nctx.more = dl->tx_hist[h].more;
+ if (length)
+ memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
+ }
+
+ /* The value of the send state variable V(S) shall be incremented by 1
+ * at the end of the transmission of the I frame */
+ dl->v_send = inc_mod(dl->v_send, dl->v_range);
+
+ /* If timer T200 is not running at the time right before transmitting a
+ * frame, when the PH-READY-TO-SEND primitive is received from the
+ * physical layer., it shall be set. */
+ if (!osmo_timer_pending(&dl->t200)) {
+ /* stop Timer T203, if running */
+ lapd_stop_t203(dl);
+ /* start Timer T200 */
+ lapd_start_t200(dl);
+ }
+
+ dl->send_ph_data_req(&nctx, msg);
+
+ rc = 0; /* we sent something */
+ goto next_frame;
+}
+
+/* request link suspension */
+static int lapd_susp_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+
+ LOGP(DLLAPD, LOGL_INFO, "perform suspension\n");
+
+ /* put back the send-buffer to the send-queue (first position) */
+ if (dl->send_buffer) {
+ LOGP(DLLAPD, LOGL_INFO, "put frame in sendbuffer back to "
+ "queue\n");
+ llist_add(&dl->send_buffer->list, &dl->send_queue);
+ dl->send_buffer = NULL;
+ } else
+ LOGP(DLLAPD, LOGL_INFO, "no frame in sendbuffer\n");
+
+ /* Clear transmit buffer, but keep send buffer */
+ lapd_dl_flush_tx(dl);
+ /* Stop timers (there is no state change, so we must stop all timers */
+ lapd_stop_t200(dl);
+ lapd_stop_t203(dl);
+
+ msgb_free(msg);
+
+ return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
+}
+
+/* requesst resume or reconnect of link */
+static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+ struct lapd_msg_ctx nctx;
+
+ LOGP(DLLAPD, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
+ msg->len);
+
+ /* be sure that history is empty */
+ lapd_dl_flush_hist(dl);
+
+ /* save message context for further use */
+ memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
+
+ /* Replace message in the send-buffer (reconnect) */
+ if (dl->send_buffer)
+ msgb_free(dl->send_buffer);
+ dl->send_out = 0;
+ if (msg && msg->len)
+ /* Write data into the send buffer, to be sent first */
+ dl->send_buffer = msg;
+ else
+ dl->send_buffer = NULL;
+
+ /* Discard partly received L3 message */
+ if (dl->rcv_buffer) {
+ msgb_free(dl->rcv_buffer);
+ dl->rcv_buffer = NULL;
+ }
+
+ /* Create new msgb (old one is now free) */
+ msg = lapd_msgb_alloc(0, "LAPD SABM");
+ msg->l3h = msg->data;
+ /* assemble message */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_U;
+ nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
+ nctx.p_f = 1;
+ nctx.length = 0;
+ nctx.more = 0;
+
+ dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
+ msgb_put(dl->tx_hist[0].msg, msg->len);
+ if (msg->len)
+ memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
+ dl->tx_hist[0].more = 0;
+ /* set Vs to 0, because it is used as index when resending SABM */
+ dl->v_send = 0;
+
+ /* Set states */
+ dl->own_busy = dl->peer_busy = 0;
+ dl->retrans_ctr = 0;
+ lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
+
+ /* Tramsmit and start T200 */
+ dl->send_ph_data_req(&nctx, msg);
+ lapd_start_t200(dl);
+
+ return 0;
+}
+
+/* requesst release of link */
+static int lapd_rel_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+ struct lapd_msg_ctx nctx;
+
+ /* local release */
+ if (dp->u.rel_req.mode) {
+ LOGP(DLLAPD, LOGL_INFO, "perform local release\n");
+ msgb_free(msg);
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
+ /* enter idle state, T203 is stopped here, if running */
+ lapd_dl_newstate(dl, LAPD_STATE_IDLE);
+ /* flush buffers */
+ lapd_dl_flush_tx(dl);
+ lapd_dl_flush_send(dl);
+ /* send notification to L3 */
+ return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
+ }
+
+ /* in case we are already disconnecting */
+ if (dl->state == LAPD_STATE_DISC_SENT)
+ return -EBUSY;
+
+ /* flush tx_hist */
+ lapd_dl_flush_hist(dl);
+
+ LOGP(DLLAPD, LOGL_INFO, "perform normal release (DISC)\n");
+
+ /* Push LAPD header on msgb */
+ /* assemble message */
+ memcpy(&nctx, &dl->lctx, sizeof(nctx));
+ /* keep nctx.ldp */
+ /* keep nctx.sapi */
+ /* keep nctx.tei */
+ nctx.cr = dl->cr.loc2rem.cmd;
+ nctx.format = LAPD_FORM_U;
+ nctx.s_u = LAPD_U_DISC;
+ nctx.p_f = 1;
+ nctx.length = 0;
+ nctx.more = 0;
+
+ dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
+ msgb_put(dl->tx_hist[0].msg, msg->len);
+ if (msg->len)
+ memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
+ dl->tx_hist[0].more = 0;
+ /* set Vs to 0, because it is used as index when resending DISC */
+ dl->v_send = 0;
+
+ /* Set states */
+ dl->own_busy = dl->peer_busy = 0;
+ dl->retrans_ctr = 0;
+ lapd_dl_newstate(dl, LAPD_STATE_DISC_SENT);
+
+ /* Tramsmit and start T200 */
+ dl->send_ph_data_req(&nctx, msg);
+ lapd_start_t200(dl);
+
+ return 0;
+}
+
+/* request release of link in idle state */
+static int lapd_rel_req_idle(struct osmo_dlsap_prim *dp,
+ struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ struct msgb *msg = dp->oph.msg;
+
+ msgb_free(msg);
+
+ /* send notification to L3 */
+ return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
+}
+
+/* statefull handling for DL SAP messages from L3 */
+static struct l2downstate {
+ uint32_t states;
+ int prim, op;
+ const char *name;
+ int (*rout) (struct osmo_dlsap_prim *dp,
+ struct lapd_msg_ctx *lctx);
+} l2downstatelist[] = {
+ /* create and send UI command */
+ {ALL_STATES,
+ PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST,
+ "DL-UNIT-DATA-REQUEST", lapd_udata_req},
+
+ /* create and send SABM command */
+ {SBIT(LAPD_STATE_IDLE),
+ PRIM_DL_EST, PRIM_OP_REQUEST,
+ "DL-ESTABLISH-REQUEST", lapd_est_req},
+
+ /* create and send I command */
+ {SBIT(LAPD_STATE_MF_EST) |
+ SBIT(LAPD_STATE_TIMER_RECOV),
+ PRIM_DL_DATA, PRIM_OP_REQUEST,
+ "DL-DATA-REQUEST", lapd_data_req},
+
+ /* suspend datalink */
+ {SBIT(LAPD_STATE_MF_EST) |
+ SBIT(LAPD_STATE_TIMER_RECOV),
+ PRIM_DL_SUSP, PRIM_OP_REQUEST,
+ "DL-SUSPEND-REQUEST", lapd_susp_req},
+
+ /* create and send SABM command (resume) */
+ {SBIT(LAPD_STATE_MF_EST) |
+ SBIT(LAPD_STATE_TIMER_RECOV),
+ PRIM_DL_RES, PRIM_OP_REQUEST,
+ "DL-RESUME-REQUEST", lapd_res_req},
+
+ /* create and send SABM command (reconnect) */
+ {SBIT(LAPD_STATE_IDLE) |
+ SBIT(LAPD_STATE_MF_EST) |
+ SBIT(LAPD_STATE_TIMER_RECOV),
+ PRIM_DL_RECON, PRIM_OP_REQUEST,
+ "DL-RECONNECT-REQUEST", lapd_res_req},
+
+ /* create and send DISC command */
+ {SBIT(LAPD_STATE_SABM_SENT) |
+ SBIT(LAPD_STATE_MF_EST) |
+ SBIT(LAPD_STATE_TIMER_RECOV) |
+ SBIT(LAPD_STATE_DISC_SENT),
+ PRIM_DL_REL, PRIM_OP_REQUEST,
+ "DL-RELEASE-REQUEST", lapd_rel_req},
+
+ /* release in idle state */
+ {SBIT(LAPD_STATE_IDLE),
+ PRIM_DL_REL, PRIM_OP_REQUEST,
+ "DL-RELEASE-REQUEST", lapd_rel_req_idle},
+};
+
+#define L2DOWNSLLEN \
+ (sizeof(l2downstatelist) / sizeof(struct l2downstate))
+
+int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
+{
+ struct lapd_datalink *dl = lctx->dl;
+ int i, supported = 0;
+ struct msgb *msg = dp->oph.msg;
+ int rc;
+
+ /* find function for current state and message */
+ for (i = 0; i < L2DOWNSLLEN; i++) {
+ if (dp->oph.primitive == l2downstatelist[i].prim
+ && dp->oph.operation == l2downstatelist[i].op) {
+ supported = 1;
+ if ((SBIT(dl->state) & l2downstatelist[i].states))
+ break;
+ }
+ }
+ if (!supported) {
+ LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unsupported.\n",
+ dp->oph.primitive, dp->oph.operation);
+ msgb_free(msg);
+ return 0;
+ }
+ if (i == L2DOWNSLLEN) {
+ LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unhandled at this "
+ "state %s.\n", dp->oph.primitive, dp->oph.operation,
+ lapd_state_names[dl->state]);
+ msgb_free(msg);
+ return 0;
+ }
+
+ LOGP(DLLAPD, LOGL_INFO, "Message %s received in state %s\n",
+ l2downstatelist[i].name, lapd_state_names[dl->state]);
+
+ rc = l2downstatelist[i].rout(dp, lctx);
+
+ return rc;
+}
+
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/lapdm.c b/Src/osmolib/src/shared/libosmocore/src/gsm/lapdm.c
index f99c119..e9ce881 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsm/lapdm.c
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/lapdm.c
@@ -1,7 +1,7 @@
/* GSM LAPDm (TS 04.06) implementation */
/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
*
* All Rights Reserved
*
@@ -27,36 +27,6 @@
/*! \file lapdm.c */
-/*!
- * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
- *
- * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
- * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
- * received while there is an incomplete rcv_buffer, it is appended to it.
- *
- * TX data is stored in the send_queue first. When transmitting a frame,
- * the first message in the send_queue is moved to the send_buffer. There it
- * resides until all fragments are acknowledged. Fragments to be sent by I
- * frames are stored in the tx_hist buffer for resend, if required. Also the
- * current fragment is copied into the tx_queue. There it resides until it is
- * forwarded to layer 1.
- *
- * In case we have SAPI 0, we only have a window size of 1, so the unack-
- * nowledged message resides always in the send_buffer. In case of a suspend,
- * it can be written back to the first position of the send_queue.
- *
- * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
- * asynchronous transfer between layer 1 and layer 2 (serial link), we must
- * send a frame before layer 1 reaches the right timeslot to send it. So we
- * move the tx_queue to layer 1 when there is not already a pending frame, and
- * wait until acknowledge after the frame has been sent. If we receive an
- * acknowledge, we can send the next frame from the buffer, if any.
- *
- * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
- * will trigger next I frame, if possible.
- *
- */
-
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -84,6 +54,7 @@
#define LAPDm_SAPI_SMS 3
#define LAPDm_ADDR(lpd, sapi, cr) ((((lpd) & 0x3) << 5) | (((sapi) & 0x7) << 2) | (((cr) & 0x1) << 1) | 0x1)
+#define LAPDm_ADDR_LPD(addr) (((addr) >> 5) & 0x3)
#define LAPDm_ADDR_SAPI(addr) (((addr) >> 2) & 0x7)
#define LAPDm_ADDR_CR(addr) (((addr) >> 1) & 0x1)
#define LAPDm_ADDR_EA(addr) ((addr) & 0x1)
@@ -105,19 +76,11 @@
#define LAPDm_CTRL_I_Ns(ctrl) (((ctrl) & 0xE) >> 1)
#define LAPDm_CTRL_Nr(ctrl) (((ctrl) & 0xE0) >> 5)
-/* TS 04.06 Table 4 / Section 3.8.1 */
-#define LAPDm_U_SABM 0x7
-#define LAPDm_U_DM 0x3
-#define LAPDm_U_UI 0x0
-#define LAPDm_U_DISC 0x8
-#define LAPDm_U_UA 0xC
-
-#define LAPDm_S_RR 0x0
-#define LAPDm_S_RNR 0x1
-#define LAPDm_S_REJ 0x2
-
#define LAPDm_LEN(len) ((len << 2) | 0x1)
#define LAPDm_MORE 0x2
+#define LAPDm_EL 0x1
+
+#define LAPDm_U_UI 0x0
/* TS 04.06 Section 5.8.3 */
#define N201_AB_SACCH 18
@@ -137,19 +100,8 @@
#define N200_TR_FACCH_FR 34
#define N200_TR_EFACCH_FR 48
#define N200_TR_FACCH_HR 29
-/* FIXME: this depends on chan type */
-#define N200 N200_TR_SACCH
-
-#define CR_MS2BS_CMD 0
-#define CR_MS2BS_RESP 1
-#define CR_BS2MS_CMD 1
-#define CR_BS2MS_RESP 0
-
-/* Set T200 to 1 Second (OpenBTS uses 900ms) */
-#define T200 1, 0
-
-/* k value for each SAPI */
-static uint8_t k_sapi[] = {1, 1, 1, 1, 1, 1, 1, 1};
+/* FIXME: set N200 depending on chan_nr */
+#define N200 N200_TR_SDCCH
enum lapdm_format {
LAPDm_FMT_A,
@@ -159,48 +111,35 @@ enum lapdm_format {
LAPDm_FMT_B4,
};
-static void lapdm_t200_cb(void *data);
-static int rslms_send_i(struct lapdm_msg_ctx *mctx, int line);
-
-/* UTILITY FUNCTIONS */
-
-static inline uint8_t inc_mod8(uint8_t x)
-{
- return (x + 1) & 7;
-}
-
-static inline uint8_t add_mod8(uint8_t x, uint8_t y)
-{
- return (x + y) & 7;
-}
-
-static inline uint8_t sub_mod8(uint8_t x, uint8_t y)
-{
- return (x - y) & 7; /* handle negative results correctly */
-}
+static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg);
+static int send_rslms_dlsap(struct osmo_dlsap_prim *dp,
+ struct lapd_msg_ctx *lctx);
static void lapdm_dl_init(struct lapdm_datalink *dl,
- struct lapdm_entity *entity)
+ struct lapdm_entity *entity, int t200)
{
memset(dl, 0, sizeof(*dl));
- INIT_LLIST_HEAD(&dl->send_queue);
- INIT_LLIST_HEAD(&dl->tx_queue);
- dl->state = LAPDm_STATE_IDLE;
- dl->t200.data = dl;
- dl->t200.cb = &lapdm_t200_cb;
dl->entity = entity;
+ lapd_dl_init(&dl->dl, 1, 8, 200);
+ dl->dl.reestablish = 0; /* GSM uses no reestablish */
+ dl->dl.send_ph_data_req = lapdm_send_ph_data_req;
+ dl->dl.send_dlsap = send_rslms_dlsap;
+ dl->dl.n200_est_rel = N200_EST_REL;
+ dl->dl.n200 = N200;
+ dl->dl.t203_sec = 0; dl->dl.t203_usec = 0;
+ dl->dl.t200_sec = t200; dl->dl.t200_usec = 0;
}
/*! \brief initialize a LAPDm entity and all datalinks inside
* \param[in] le LAPDm entity
* \param[in] mode \ref lapdm_mode (BTS/MS)
*/
-void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode)
+void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(le->datalink); i++)
- lapdm_dl_init(&le->datalink[i], le);
+ lapdm_dl_init(&le->datalink[i], le, t200);
lapdm_entity_set_mode(le, mode);
}
@@ -214,34 +153,9 @@ void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode)
*/
void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode)
{
- lapdm_entity_init(&lc->lapdm_acch, mode);
- lapdm_entity_init(&lc->lapdm_dcch, mode);
-}
-
-static void lapdm_dl_flush_send(struct lapdm_datalink *dl)
-{
- struct msgb *msg;
-
- /* Flush send-queue */
- while ((msg = msgb_dequeue(&dl->send_queue)))
- msgb_free(msg);
-
- /* Clear send-buffer */
- if (dl->send_buffer) {
- msgb_free(dl->send_buffer);
- dl->send_buffer = NULL;
- }
-}
-
-static void lapdm_dl_flush_tx(struct lapdm_datalink *dl)
-{
- struct msgb *msg;
- unsigned int i;
-
- while ((msg = msgb_dequeue(&dl->tx_queue)))
- msgb_free(msg);
- for (i = 0; i < 8; i++)
- dl->tx_length[i] = 0;
+ lapdm_entity_init(&lc->lapdm_acch, mode, 2);
+ /* FIXME: this depends on chan type */
+ lapdm_entity_init(&lc->lapdm_dcch, mode, 1);
}
/*! \brief flush and release all resoures in LAPDm entity */
@@ -252,10 +166,7 @@ void lapdm_entity_exit(struct lapdm_entity *le)
for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
dl = &le->datalink[i];
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- if (dl->rcv_buffer)
- msgb_free(dl->rcv_buffer);
+ lapd_dl_exit(&dl->dl);
}
}
@@ -270,14 +181,6 @@ void lapdm_channel_exit(struct lapdm_channel *lc)
lapdm_entity_exit(&lc->lapdm_dcch);
}
-static void lapdm_dl_newstate(struct lapdm_datalink *dl, uint32_t state)
-{
- LOGP(DLLAPDM, LOGL_INFO, "new state %s -> %s\n",
- lapdm_state_names[dl->state], lapdm_state_names[state]);
-
- dl->state = state;
-}
-
static struct lapdm_datalink *datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi)
{
switch (sapi) {
@@ -305,7 +208,7 @@ static void lapdm_pad_msgb(struct msgb *msg, uint8_t n201)
uint8_t *data;
if (pad_len < 0) {
- LOGP(DLLAPDM, LOGL_ERROR,
+ LOGP(DLLAPD, LOGL_ERROR,
"cannot pad message that is already too big!\n");
return;
}
@@ -328,17 +231,17 @@ static int rslms_sendmsg(struct msgb *msg, struct lapdm_entity *le)
/* write a frame into the tx queue */
static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
- uint8_t chan_nr, uint8_t link_id, uint8_t n201)
+ uint8_t chan_nr, uint8_t link_id, uint8_t pad)
{
struct lapdm_entity *le = dl->entity;
struct osmo_phsap_prim pp;
/* if there is a pending message, queue it */
if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) {
- *msgb_push(msg, 1) = n201;
+ *msgb_push(msg, 1) = pad;
*msgb_push(msg, 1) = link_id;
*msgb_push(msg, 1) = chan_nr;
- msgb_enqueue(&dl->tx_queue, msg);
+ msgb_enqueue(&dl->dl.tx_queue, msg);
return -EBUSY;
}
@@ -349,7 +252,7 @@ static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
/* send the frame now */
le->tx_pending = 0; /* disabled flow control */
- lapdm_pad_msgb(msg, n201);
+ lapdm_pad_msgb(msg, pad);
return le->l1_prim_cb(&pp.oph, le->l1_ctx);
}
@@ -366,7 +269,7 @@ static struct msgb *tx_dequeue_msgb(struct lapdm_entity *le)
/* next */
i = (i + 1) % n;
dl = &le->datalink[i];
- if ((msg = msgb_dequeue(&dl->tx_queue)))
+ if ((msg = msgb_dequeue(&dl->dl.tx_queue)))
break;
} while (i != last);
@@ -383,7 +286,7 @@ static struct msgb *tx_dequeue_msgb(struct lapdm_entity *le)
int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp)
{
struct msgb *msg;
- uint8_t n201;
+ uint8_t pad;
msg = tx_dequeue_msgb(le);
if (!msg)
@@ -398,11 +301,11 @@ int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp
msgb_pull(msg, 1);
pp->u.data.link_id = *msg->data;
msgb_pull(msg, 1);
- n201 = *msg->data;
+ pad = *msg->data;
msgb_pull(msg, 1);
/* Pad the frame, we can transmit now */
- lapdm_pad_msgb(msg, n201);
+ lapdm_pad_msgb(msg, pad);
return 0;
}
@@ -486,1157 +389,148 @@ static int rsl_rll_error(uint8_t cause, struct lapdm_msg_ctx *mctx)
{
struct msgb *msg;
- LOGP(DLLAPDM, LOGL_NOTICE, "sending MDL-ERROR-IND %d\n", cause);
+ LOGP(DLLAPD, LOGL_NOTICE, "sending MDL-ERROR-IND %d\n", cause);
msg = rsl_rll_simple(RSL_MT_ERROR_IND, mctx->chan_nr, mctx->link_id, 1);
msg->l2h = msgb_put(msg, sizeof(struct abis_rsl_rll_hdr));
msgb_tlv_put(msg, RSL_IE_RLM_CAUSE, 1, &cause);
return rslms_sendmsg(msg, mctx->dl->entity);
}
-static int check_length_ind(struct lapdm_msg_ctx *mctx, uint8_t length_ind)
-{
- if (!(length_ind & 0x01)) {
- /* G.4.1 If the EL bit is set to "0", an MDL-ERROR-INDICATION
- * primitive with cause "frame not implemented" is sent to the
- * mobile management entity. */
- LOGP(DLLAPDM, LOGL_NOTICE,
- "we don't support multi-octet length\n");
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- return 0;
-}
-
-static int lapdm_send_resend(struct lapdm_datalink *dl)
+/* DLSAP L2 -> L3 (RSLms) */
+static int send_rslms_dlsap(struct osmo_dlsap_prim *dp,
+ struct lapd_msg_ctx *lctx)
{
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm resend");
- int length;
-
- /* Resend SABM/DISC from tx_hist */
- length = dl->tx_length[0];
- msg->l2h = msgb_put(msg, length);
- memcpy(msg->l2h, dl->tx_hist[dl->V_send], length);
-
- return tx_ph_data_enqueue(dl, msg, dl->mctx.chan_nr, dl->mctx.link_id,
- dl->mctx.n201);
-}
-
-static int lapdm_send_ua(struct lapdm_msg_ctx *mctx, uint8_t len, uint8_t *data)
-{
- uint8_t sapi = mctx->link_id & 7;
- uint8_t f_bit = LAPDm_CTRL_PF_BIT(mctx->ctrl);
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm UA");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3 + len);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_UA, f_bit);
- msg->l2h[2] = LAPDm_LEN(len);
- if (len)
- memcpy(msg->l2h + 3, data, len);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_dm(struct lapdm_msg_ctx *mctx)
-{
- uint8_t sapi = mctx->link_id & 7;
- uint8_t f_bit = LAPDm_CTRL_PF_BIT(mctx->ctrl);
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm DM");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_DM, f_bit);
- msg->l2h[2] = 0;
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_rr(struct lapdm_msg_ctx *mctx, uint8_t f_bit)
-{
- uint8_t sapi = mctx->link_id & 7;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RR");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_S(mctx->dl->V_recv, LAPDm_S_RR, f_bit);
- msg->l2h[2] = LAPDm_LEN(0);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_rnr(struct lapdm_msg_ctx *mctx, uint8_t f_bit)
-{
- uint8_t sapi = mctx->link_id & 7;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RNR");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_S(mctx->dl->V_recv, LAPDm_S_RNR, f_bit);
- msg->l2h[2] = LAPDm_LEN(0);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_rej(struct lapdm_msg_ctx *mctx, uint8_t f_bit)
-{
- uint8_t sapi = mctx->link_id & 7;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm REJ");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_S(mctx->dl->V_recv, LAPDm_S_REJ, f_bit);
- msg->l2h[2] = LAPDm_LEN(0);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-/* Timer callback on T200 expiry */
-static void lapdm_t200_cb(void *data)
-{
- struct lapdm_datalink *dl = data;
-
- LOGP(DLLAPDM, LOGL_INFO, "lapdm_t200_cb(%p) state=%u\n", dl, dl->state);
-
- switch (dl->state) {
- case LAPDm_STATE_SABM_SENT:
- /* 5.4.1.3 */
- if (dl->retrans_ctr + 1 >= N200_EST_REL + 1) {
- /* send RELEASE INDICATION to L3 */
- send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- /* send MDL ERROR INIDCATION to L3 */
- rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- /* flush tx buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* go back to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* NOTE: we must not change any other states or buffers
- * and queues, since we may reconnect after handover
- * failure. the buffered messages is replaced there */
- break;
- }
- /* retransmit SABM command */
- lapdm_send_resend(dl);
- /* increment re-transmission counter */
- dl->retrans_ctr++;
- /* restart T200 (PH-READY-TO-SEND) */
- osmo_timer_schedule(&dl->t200, T200);
+ struct lapd_datalink *dl = lctx->dl;
+ struct lapdm_datalink *mdl =
+ container_of(dl, struct lapdm_datalink, dl);
+ struct lapdm_msg_ctx *mctx = &mdl->mctx;
+ uint8_t rll_msg = 0;
+
+ switch (OSMO_PRIM_HDR(&dp->oph)) {
+ case OSMO_PRIM(PRIM_DL_EST, PRIM_OP_INDICATION):
+ rll_msg = RSL_MT_EST_IND;
break;
- case LAPDm_STATE_DISC_SENT:
- /* 5.4.4.3 */
- if (dl->retrans_ctr + 1 >= N200_EST_REL + 1) {
- /* send RELEASE INDICATION to L3 */
- send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
- /* send MDL ERROR INIDCATION to L3 */
- rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- /* flush buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* go back to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* NOTE: we must not change any other states or buffers
- * and queues, since we may reconnect after handover
- * failure. the buffered messages is replaced there */
- break;
- }
- /* retransmit DISC command */
- lapdm_send_resend(dl);
- /* increment re-transmission counter */
- dl->retrans_ctr++;
- /* restart T200 (PH-READY-TO-SEND) */
- osmo_timer_schedule(&dl->t200, T200);
+ case OSMO_PRIM(PRIM_DL_EST, PRIM_OP_CONFIRM):
+ rll_msg = RSL_MT_EST_CONF;
break;
- case LAPDm_STATE_MF_EST:
- /* 5.5.7 */
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_TIMER_RECOV);
- /* fall through */
- case LAPDm_STATE_TIMER_RECOV:
- dl->retrans_ctr++;
- if (dl->retrans_ctr < N200) {
- /* retransmit I frame (V_s-1) with P=1, if any */
- if (dl->tx_length[sub_mod8(dl->V_send, 1)]) {
- struct msgb *msg;
- int length;
-
- LOGP(DLLAPDM, LOGL_INFO, "retransmit last frame "
- "V(S)=%d\n", sub_mod8(dl->V_send, 1));
- /* Create I frame (segment) from tx_hist */
- length = dl->tx_length[sub_mod8(dl->V_send, 1)];
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm I");
- msg->l2h = msgb_put(msg, length);
- memcpy(msg->l2h,
- dl->tx_hist[sub_mod8(dl->V_send, 1)],
- length);
- msg->l2h[1] = LAPDm_CTRL_I(dl->V_recv,
- sub_mod8(dl->V_send, 1), 1); /* P=1 */
- tx_ph_data_enqueue(dl, msg, dl->mctx.chan_nr,
- dl->mctx.link_id, dl->mctx.n201);
- } else {
- /* OR send appropriate supervision frame with P=1 */
- if (!dl->own_busy && !dl->seq_err_cond) {
- lapdm_send_rr(&dl->mctx, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- lapdm_send_rnr(&dl->mctx, 1);
- } else {
- LOGP(DLLAPDM, LOGL_INFO, "unhandled, "
- "pls. fix\n");
- }
- }
- /* restart T200 (PH-READY-TO-SEND) */
- osmo_timer_schedule(&dl->t200, T200);
- } else {
- /* send MDL ERROR INIDCATION to L3 */
- rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- }
+ case OSMO_PRIM(PRIM_DL_DATA, PRIM_OP_INDICATION):
+ rll_msg = RSL_MT_DATA_IND;
break;
- default:
- LOGP(DLLAPDM, LOGL_INFO, "T200 expired in unexpected "
- "dl->state %u\n", dl->state);
- }
-}
-
-/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
-static void lapdm_acknowledge(struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- uint8_t nr = LAPDm_CTRL_Nr(mctx->ctrl);
- int s = 0, rej = 0, t200_reset = 0;
- int i;
-
- /* supervisory frame ? */
- if (LAPDm_CTRL_is_S(mctx->ctrl))
- s = 1;
- /* REJ frame ? */
- if (s && LAPDm_CTRL_S_BITS(mctx->ctrl) == LAPDm_S_REJ)
- rej = 1;
-
- /* Flush all transmit buffers of acknowledged frames */
- for (i = dl->V_ack; i != nr; i = inc_mod8(i)) {
- if (dl->tx_length[i]) {
- dl->tx_length[i] = 0;
- LOGP(DLLAPDM, LOGL_INFO, "ack frame %d\n", i);
- }
- }
-
- if (dl->state != LAPDm_STATE_TIMER_RECOV) {
- /* When not in the timer recovery condition, the data
- * link layer entity shall reset the timer T200 on
- * receipt of a valid I frame with N(R) higher than V(A),
- * or an REJ with an N(R) equal to V(A). */
- if ((!rej && nr != dl->V_ack)
- || (rej && nr == dl->V_ack)) {
- LOGP(DLLAPDM, LOGL_INFO, "reset t200\n");
- t200_reset = 1;
- osmo_timer_del(&dl->t200);
- /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
- }
- /* 5.7.4: N(R) sequence error
- * N(R) is called valid, if and only if
- * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
- */
- if (sub_mod8(nr, dl->V_ack) > sub_mod8(dl->V_send, dl->V_ack)) {
- LOGP(DLLAPDM, LOGL_NOTICE, "N(R) sequence error\n");
- rsl_rll_error(RLL_CAUSE_SEQ_ERR, mctx);
- }
- }
-
- /* V(A) shall be set to the value of N(R) */
- dl->V_ack = nr;
-
- /* If T200 has been reset by the receipt of an I, RR or RNR frame,
- * and if there are outstanding I frames, restart T200 */
- if (t200_reset && !rej) {
- if (dl->tx_length[dl->V_send - 1]) {
- LOGP(DLLAPDM, LOGL_INFO, "start T200, due to unacked I "
- "frame(s)\n");
- osmo_timer_schedule(&dl->t200, T200);
- }
- }
-}
-
-/* L1 -> L2 */
-
-/* Receive a LAPDm U (Unnumbered) message from L1 */
-static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- uint8_t length;
- int rc;
- int rsl_msg;
-
- switch (LAPDm_CTRL_U_BITS(mctx->ctrl)) {
- case LAPDm_U_SABM:
- rsl_msg = RSL_MT_EST_IND;
-
- LOGP(DLLAPDM, LOGL_INFO, "SABM received\n");
- /* 5.7.1 */
- dl->seq_err_cond = 0;
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLLAPDM, LOGL_NOTICE, "SABM response error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- /* G.4.5 If SABM is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if ((msg->l2h[2] & LAPDm_MORE) || length + 3 > mctx->n201) {
- LOGP(DLLAPDM, LOGL_NOTICE, "SABM too large error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_UFRM_INC_PARAM, mctx);
- return -EIO;
- }
-
- /* Must be Format B */
- rc = check_length_ind(mctx, msg->l2h[2]);
- if (rc < 0) {
- msgb_free(msg);
- return rc;
- }
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- /* Set chan_nr and link_id for established connection */
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.chan_nr = mctx->chan_nr;
- dl->mctx.link_id = mctx->link_id;
- dl->mctx.n201 = mctx->n201;
- break;
- case LAPDm_STATE_MF_EST:
- if (length == 0) {
- rsl_msg = RSL_MT_EST_CONF;
- break;
- }
- LOGP(DLLAPDM, LOGL_INFO, "SABM command, multiple "
- "frame established state\n");
- /* check for contention resoultion */
- if (dl->tx_hist[0][2] >> 2) {
- LOGP(DLLAPDM, LOGL_NOTICE, "SABM not allowed "
- "during contention resolution\n");
- rsl_rll_error(RLL_CAUSE_SABM_INFO_NOTALL, mctx);
- }
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_DISC_SENT:
- /* 5.4.6.2 send DM with F=P */
- lapdm_send_dm(mctx);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_CONF, mctx);
- default:
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- msgb_free(msg);
- return 0;
- }
- /* send UA response */
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- /* set Vs, Vr and Va to 0 */
- dl->V_send = dl->V_recv = dl->V_ack = 0;
- /* clear tx_hist */
- dl->tx_length[0] = 0;
- /* enter multiple-frame-established state */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* send notification to L3 */
- if (length == 0) {
- /* 5.4.1.2 Normal establishment procedures */
- rc = send_rll_simple(rsl_msg, mctx);
- msgb_free(msg);
- } else {
- /* 5.4.1.4 Contention resolution establishment */
- msg->l3h = msg->l2h + 3;
- msgb_pull_l2h(msg);
- rc = send_rslms_rll_l3(rsl_msg, mctx, msg);
- }
+ case OSMO_PRIM(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION):
+ return send_rslms_rll_l3_ui(mctx, dp->oph.msg);
+ case OSMO_PRIM(PRIM_DL_REL, PRIM_OP_INDICATION):
+ rll_msg = RSL_MT_REL_IND;
break;
- case LAPDm_U_DM:
- LOGP(DLLAPDM, LOGL_INFO, "DM received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd) {
- LOGP(DLLAPDM, LOGL_NOTICE, "DM command error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- if (!LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- /* 5.4.1.2 DM responses with the F bit set to "0"
- * shall be ignored.
- */
- msgb_free(msg);
- return 0;
- }
- switch (dl->state) {
- case LAPDm_STATE_SABM_SENT:
- break;
- case LAPDm_STATE_MF_EST:
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl) == 1) {
- LOGP(DLLAPDM, LOGL_INFO, "unsolicited DM "
- "response\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_DM_RESP, mctx);
- } else {
- LOGP(DLLAPDM, LOGL_INFO, "unsolicited DM "
- "response, multiple frame established "
- "state\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_DM_RESP_MF, mctx);
- }
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_TIMER_RECOV:
- /* DM is normal in case PF = 1 */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl) == 0) {
- LOGP(DLLAPDM, LOGL_INFO, "unsolicited DM "
- "response, multiple frame established "
- "state\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_DM_RESP_MF, mctx);
- msgb_free(msg);
- return 0;
- }
- break;
- case LAPDm_STATE_DISC_SENT:
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* go to idle state */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- rc = send_rll_simple(RSL_MT_REL_CONF, mctx);
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_IDLE:
- /* 5.4.5 all other frame types shall be discarded */
- default:
- LOGP(DLLAPDM, LOGL_INFO, "unsolicited DM response! "
- "(discarding)\n");
- msgb_free(msg);
- return 0;
- }
- /* reset T200 */
- osmo_timer_del(&dl->t200);
- rc = send_rll_simple(RSL_MT_REL_IND, mctx);
- msgb_free(msg);
- break;
- case LAPDm_U_UI:
- LOGP(DLLAPDM, LOGL_INFO, "UI received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLLAPDM, LOGL_NOTICE, "UI indicates response "
- "error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- /* FIXME: G.4.5 If UI is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
-
- if (mctx->lapdm_fmt == LAPDm_FMT_B4) {
- length = N201_B4;
- msg->l3h = msg->l2h + 2;
- } else {
- rc = check_length_ind(mctx, msg->l2h[2]);
- if (rc < 0) {
- msgb_free(msg);
- return rc;
- }
- length = msg->l2h[2] >> 2;
- msg->l3h = msg->l2h + 3;
- }
- /* do some length checks */
- if (length == 0) {
- /* 5.3.3 UI frames received with the length indicator
- * set to "0" shall be ignored
- */
- LOGP(DLLAPDM, LOGL_INFO, "length=0 (discarding)\n");
- msgb_free(msg);
- return 0;
- }
- switch (LAPDm_ADDR_SAPI(mctx->addr)) {
- case LAPDm_SAPI_NORMAL:
- case LAPDm_SAPI_SMS:
- break;
- default:
- /* 5.3.3 UI frames with invalid SAPI values shall be
- * discarded
- */
- LOGP(DLLAPDM, LOGL_INFO, "sapi=%u (discarding)\n",
- LAPDm_ADDR_SAPI(mctx->addr));
- msgb_free(msg);
- return 0;
- }
- msgb_pull_l2h(msg);
- rc = send_rslms_rll_l3_ui(mctx, msg);
+ case OSMO_PRIM(PRIM_DL_REL, PRIM_OP_CONFIRM):
+ rll_msg = RSL_MT_REL_CONF;
break;
- case LAPDm_U_DISC:
- rsl_msg = RSL_MT_REL_IND;
-
- LOGP(DLLAPDM, LOGL_INFO, "DISC received\n");
- /* flush buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* 5.7.1 */
- dl->seq_err_cond = 0;
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLLAPDM, LOGL_NOTICE, "DISC response error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- length = msg->l2h[2] >> 2;
- if (length > 0 || msg->l2h[2] & 0x02) {
- /* G.4.4 If a DISC or DM frame is received with L>0 or
- * with the M bit set to "1", an MDL-ERROR-INDICATION
- * primitive with cause "U frame with incorrect
- * parameters" is sent to the mobile management entity.
- */
- LOGP(DLLAPDM, LOGL_NOTICE,
- "U frame iwth incorrect parameters ");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_UFRM_INC_PARAM, mctx);
- return -EIO;
- }
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- LOGP(DLLAPDM, LOGL_INFO, "DISC in idle state\n");
- /* send DM with F=P */
- msgb_free(msg);
- return lapdm_send_dm(mctx);
- case LAPDm_STATE_SABM_SENT:
- LOGP(DLLAPDM, LOGL_INFO, "DISC in SABM state\n");
- /* 5.4.6.2 send DM with F=P */
- lapdm_send_dm(mctx);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, mctx);
- case LAPDm_STATE_MF_EST:
- case LAPDm_STATE_TIMER_RECOV:
- LOGP(DLLAPDM, LOGL_INFO, "DISC in est state\n");
- break;
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLLAPDM, LOGL_INFO, "DISC in disc state\n");
- rsl_msg = RSL_MT_REL_CONF;
- break;
- default:
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- msgb_free(msg);
- return 0;
- }
- /* send UA response */
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* enter idle state */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* send notification to L3 */
- rc = send_rll_simple(rsl_msg, mctx);
- msgb_free(msg);
+ case OSMO_PRIM(PRIM_DL_SUSP, PRIM_OP_CONFIRM):
+ rll_msg = RSL_MT_SUSP_CONF;
break;
- case LAPDm_U_UA:
- LOGP(DLLAPDM, LOGL_INFO, "UA received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd) {
- LOGP(DLLAPDM, LOGL_NOTICE, "UA indicates command "
- "error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- /* G.4.5 If UA is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if ((msg->l2h[2] & LAPDm_MORE) || length + 3 > mctx->n201) {
- LOGP(DLLAPDM, LOGL_NOTICE, "UA too large error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_UFRM_INC_PARAM, mctx);
- return -EIO;
- }
-
- if (!LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- /* 5.4.1.2 A UA response with the F bit set to "0"
- * shall be ignored.
- */
- LOGP(DLLAPDM, LOGL_INFO, "F=0 (discarding)\n");
- msgb_free(msg);
- return 0;
- }
- switch (dl->state) {
- case LAPDm_STATE_SABM_SENT:
- break;
- case LAPDm_STATE_MF_EST:
- case LAPDm_STATE_TIMER_RECOV:
- LOGP(DLLAPDM, LOGL_INFO, "unsolicited UA response! "
- "(discarding)\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_UA_RESP, mctx);
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLLAPDM, LOGL_INFO, "UA in disconnect state\n");
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* go to idle state */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- rc = send_rll_simple(RSL_MT_REL_CONF, mctx);
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_IDLE:
- /* 5.4.5 all other frame types shall be discarded */
- default:
- LOGP(DLLAPDM, LOGL_INFO, "unsolicited UA response! "
- "(discarding)\n");
- msgb_free(msg);
- return 0;
- }
- LOGP(DLLAPDM, LOGL_INFO, "UA in SABM state\n");
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* compare UA with SABME if contention resolution is applied */
- if (dl->tx_hist[0][2] >> 2) {
- rc = check_length_ind(mctx, msg->l2h[2]);
- if (rc < 0) {
- rc = send_rll_simple(RSL_MT_REL_IND, mctx);
- msgb_free(msg);
- /* go to idle state */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- return 0;
- }
- length = msg->l2h[2] >> 2;
- if (length != (dl->tx_hist[0][2] >> 2)
- || !!memcmp(dl->tx_hist[0] + 3, msg->l2h + 3,
- length)) {
- LOGP(DLLAPDM, LOGL_INFO, "**** UA response "
- "mismatches ****\n");
- rc = send_rll_simple(RSL_MT_REL_IND, mctx);
- msgb_free(msg);
- /* go to idle state */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- return 0;
- }
- }
- /* set Vs, Vr and Va to 0 */
- dl->V_send = dl->V_recv = dl->V_ack = 0;
- /* clear tx_hist */
- dl->tx_length[0] = 0;
- /* enter multiple-frame-established state */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* send outstanding frames, if any (resume / reconnect) */
- rslms_send_i(mctx, __LINE__);
- /* send notification to L3 */
- rc = send_rll_simple(RSL_MT_EST_CONF, mctx);
- msgb_free(msg);
- break;
- default:
- /* G.3.1 */
- LOGP(DLLAPDM, LOGL_NOTICE, "Unnumbered frame not allowed.\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
+ case OSMO_PRIM(PRIM_MDL_ERROR, PRIM_OP_INDICATION):
+ rsl_rll_error(dp->u.error_ind.cause, mctx);
+ if (dp->oph.msg)
+ msgb_free(dp->oph.msg);
+ return 0;
}
- return rc;
-}
-
-/* Receive a LAPDm S (Supervisory) message from L1 */
-static int lapdm_rx_s(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- uint8_t length;
- length = msg->l2h[2] >> 2;
- if (length > 0 || msg->l2h[2] & 0x02) {
- /* G.4.3 If a supervisory frame is received with L>0 or
- * with the M bit set to "1", an MDL-ERROR-INDICATION
- * primitive with cause "S frame with incorrect
- * parameters" is sent to the mobile management entity. */
- LOGP(DLLAPDM, LOGL_NOTICE,
- "S frame with incorrect parameters\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_SFRM_INC_PARAM, mctx);
- return -EIO;
+ if (!rll_msg) {
+ LOGP(DLLAPD, LOGL_ERROR, "Unsupported op %d, prim %d. Please "
+ "fix!\n", dp->oph.primitive, dp->oph.operation);
+ return -EINVAL;
}
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)
- && dl->state != LAPDm_STATE_TIMER_RECOV) {
- /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
- LOGP(DLLAPDM, LOGL_NOTICE, "S frame response with F=1 error\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_SPRV_RESP, mctx);
- }
+ if (!dp->oph.msg)
+ return send_rll_simple(rll_msg, mctx);
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- /* if P=1, respond DM with F=1 (5.2.2) */
- /* 5.4.5 all other frame types shall be discarded */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl))
- lapdm_send_dm(mctx); /* F=P */
- /* fall though */
- case LAPDm_STATE_SABM_SENT:
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLLAPDM, LOGL_NOTICE, "S frame ignored in this state\n");
- msgb_free(msg);
- return 0;
- }
- switch (LAPDm_CTRL_S_BITS(mctx->ctrl)) {
- case LAPDm_S_RR:
- LOGP(DLLAPDM, LOGL_INFO, "RR received\n");
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapdm_acknowledge(mctx);
-
- /* 5.5.3.2 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLLAPDM, LOGL_NOTICE, "RR frame command "
- "with polling bit set and we are not "
- "busy, so we reply with RR frame\n");
- lapdm_send_rr(mctx, 1);
- /* NOTE: In case of sequence error condition,
- * the REJ frame has been transmitted when
- * entering the condition, so it has not be
- * done here
- */
- } else if (dl->own_busy) {
- LOGP(DLLAPDM, LOGL_NOTICE, "RR frame command "
- "with polling bit set and we are busy, "
- "so we reply with RR frame\n");
- lapdm_send_rnr(mctx, 1);
- }
- } else if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)
- && dl->state == LAPDm_STATE_TIMER_RECOV) {
- LOGP(DLLAPDM, LOGL_INFO, "RR response with F==1, "
- "and we are in timer recovery state, so "
- "we leave that state\n");
- /* V(S) to the N(R) in the RR frame */
- dl->V_send = LAPDm_CTRL_Nr(mctx->ctrl);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* 5.5.7 Clear timer recovery condition */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- }
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
+ return send_rslms_rll_l3(rll_msg, mctx, dp->oph.msg);
+}
+/* send a data frame to layer 1 */
+static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg)
+{
+ uint8_t l3_len = msg->tail - msg->data;
+ struct lapd_datalink *dl = lctx->dl;
+ struct lapdm_datalink *mdl =
+ container_of(dl, struct lapdm_datalink, dl);
+ struct lapdm_msg_ctx *mctx = &mdl->mctx;
+ int format = lctx->format;
+
+ /* prepend l2 header */
+ msg->l2h = msgb_push(msg, 3);
+ msg->l2h[0] = LAPDm_ADDR(lctx->lpd, lctx->sapi, lctx->cr);
+ /* EA is set here too */
+ switch (format) {
+ case LAPD_FORM_I:
+ msg->l2h[1] = LAPDm_CTRL_I(lctx->n_recv, lctx->n_send,
+ lctx->p_f);
break;
- case LAPDm_S_RNR:
- LOGP(DLLAPDM, LOGL_INFO, "RNR received\n");
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapdm_acknowledge(mctx);
-
- /* 5.5.5 */
- /* Set peer receiver busy condition */
- dl->peer_busy = 1;
-
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd) {
- if (!dl->own_busy) {
- LOGP(DLLAPDM, LOGL_INFO, "RNR poll "
- "command and we are not busy, "
- "so we reply with RR final "
- "response\n");
- /* Send RR with F=1 */
- lapdm_send_rr(mctx, 1);
- } else {
- LOGP(DLLAPDM, LOGL_INFO, "RNR poll "
- "command and we are busy, so "
- "we reply with RNR final "
- "response\n");
- /* Send RNR with F=1 */
- lapdm_send_rnr(mctx, 1);
- }
- } else if (dl->state == LAPDm_STATE_TIMER_RECOV) {
- LOGP(DLLAPDM, LOGL_INFO, "RNR poll response "
- "and we in timer recovery state, so "
- "we leave that state\n");
- /* 5.5.7 Clear timer recovery condition */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* V(S) to the N(R) in the RNR frame */
- dl->V_send = LAPDm_CTRL_Nr(mctx->ctrl);
- }
- } else
- LOGP(DLLAPDM, LOGL_INFO, "RNR not polling/final state "
- "received\n");
-
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
+ case LAPD_FORM_S:
+ msg->l2h[1] = LAPDm_CTRL_S(lctx->n_recv, lctx->s_u, lctx->p_f);
break;
- case LAPDm_S_REJ:
- LOGP(DLLAPDM, LOGL_INFO, "REJ received\n");
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapdm_acknowledge(mctx);
-
- /* 5.5.4.1 */
- if (dl->state != LAPDm_STATE_TIMER_RECOV) {
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->V_send = dl->V_ack = LAPDm_CTRL_Nr(mctx->ctrl);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* 5.5.3.2 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLLAPDM, LOGL_INFO, "REJ poll "
- "command not in timer recovery "
- "state and not in own busy "
- "condition received, so we "
- "respond with RR final "
- "response\n");
- lapdm_send_rr(mctx, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- LOGP(DLLAPDM, LOGL_INFO, "REJ poll "
- "command not in timer recovery "
- "state and in own busy "
- "condition received, so we "
- "respond with RNR final "
- "response\n");
- lapdm_send_rnr(mctx, 1);
- }
- } else
- LOGP(DLLAPDM, LOGL_INFO, "REJ response or not "
- "polling command not in timer recovery "
- "state received\n");
- /* send MDL ERROR INIDCATION to L3 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- rsl_rll_error(RLL_CAUSE_UNSOL_SPRV_RESP, mctx);
- }
-
- } else if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- LOGP(DLLAPDM, LOGL_INFO, "REJ poll response in timer "
- "recovery state received\n");
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* 5.5.7 Clear timer recovery condition */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->V_send = dl->V_ack = LAPDm_CTRL_Nr(mctx->ctrl);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- } else {
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->V_send = dl->V_ack = LAPDm_CTRL_Nr(mctx->ctrl);
- /* 5.5.3.2 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLLAPDM, LOGL_INFO, "REJ poll "
- "command in timer recovery "
- "state and not in own busy "
- "condition received, so we "
- "respond with RR final "
- "response\n");
- lapdm_send_rr(mctx, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- LOGP(DLLAPDM, LOGL_INFO, "REJ poll "
- "command in timer recovery "
- "state and in own busy "
- "condition received, so we "
- "respond with RNR final "
- "response\n");
- lapdm_send_rnr(mctx, 1);
- }
- } else
- LOGP(DLLAPDM, LOGL_INFO, "REJ response or not "
- "polling command in timer recovery "
- "state received\n");
- }
-
- /* FIXME: 5.5.4.2 2) */
-
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
+ case LAPD_FORM_U:
+ msg->l2h[1] = LAPDm_CTRL_U(lctx->s_u, lctx->p_f);
break;
default:
- /* G.3.1 */
- LOGP(DLLAPDM, LOGL_NOTICE, "Supervisory frame not allowed.\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- msgb_free(msg);
- return 0;
-}
-
-/* Receive a LAPDm I (Information) message from L1 */
-static int lapdm_rx_i(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- //uint8_t nr = LAPDm_CTRL_Nr(mctx->ctrl);
- uint8_t ns = LAPDm_CTRL_I_Ns(mctx->ctrl);
- uint8_t length;
- int rc;
-
- LOGP(DLLAPDM, LOGL_NOTICE, "I received\n");
-
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLLAPDM, LOGL_NOTICE, "I frame response not allowed\n");
msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
return -EINVAL;
}
+ msg->l2h[2] = LAPDm_LEN(l3_len); /* EL is set here too */
+ if (lctx->more)
+ msg->l2h[2] |= LAPDm_MORE;
- length = msg->l2h[2] >> 2;
- if (length == 0 || length + 3 > mctx->n201) {
- /* G.4.2 If the length indicator of an I frame is set
- * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
- * primitive with cause "I frame with incorrect length"
- * is sent to the mobile management entity. */
- LOGP(DLLAPDM, LOGL_NOTICE, "I frame length not allowed\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_IFRM_INC_LEN, mctx);
- return -EIO;
- }
-
- /* G.4.2 If the numerical value of L is L<N201 and the M
- * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
- * cause "I frame with incorrect use of M bit" is sent to the
- * mobile management entity. */
- if ((msg->l2h[2] & LAPDm_MORE) && length + 3 < mctx->n201) {
- LOGP(DLLAPDM, LOGL_NOTICE, "I frame with M bit too short\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_IFRM_INC_MBITS, mctx);
- return -EIO;
- }
-
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- /* if P=1, respond DM with F=1 (5.2.2) */
- /* 5.4.5 all other frame types shall be discarded */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl))
- lapdm_send_dm(mctx); /* F=P */
- /* fall though */
- case LAPDm_STATE_SABM_SENT:
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLLAPDM, LOGL_NOTICE, "I frame ignored in this state\n");
- msgb_free(msg);
- return 0;
- }
+ /* add ACCH header with last indicated tx-power and TA */
+ if ((mctx->link_id & 0x40)) {
+ struct lapdm_entity *le = mdl->entity;
- /* 5.7.1: N(s) sequence error */
- if (ns != dl->V_recv) {
- LOGP(DLLAPDM, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
- "V(R)=%u\n", ns, dl->V_recv);
- /* discard data */
- msgb_free(msg);
- if (!dl->seq_err_cond) {
- /* FIXME: help me understand what exactly todo here
- dl->seq_err_cond = 1;
- */
- lapdm_send_rej(mctx, LAPDm_CTRL_PF_BIT(mctx->ctrl));
- } else {
- }
- return -EIO;
+ msg->l2h = msgb_push(msg, 2);
+ msg->l2h[0] = le->tx_power;
+ msg->l2h[1] = le->ta;
}
- dl->seq_err_cond = 0;
-
- /* Increment receiver state */
- dl->V_recv = inc_mod8(dl->V_recv);
- LOGP(DLLAPDM, LOGL_NOTICE, "incrementing V(R) to %u\n", dl->V_recv);
-
- /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
- lapdm_acknowledge(mctx); /* V(A) is also set here */
-
- /* Only if we are not in own receiver busy condition */
- if (!dl->own_busy) {
- /* if the frame carries a complete segment */
- if (!(msg->l2h[2] & LAPDm_MORE)
- && !dl->rcv_buffer) {
- LOGP(DLLAPDM, LOGL_INFO, "message in single I frame\n");
- /* send a DATA INDICATION to L3 */
- msg->l3h = msg->l2h + 3;
- msgb_pull_l2h(msg);
- msg->len = length;
- msg->tail = msg->data + length;
- rc = send_rslms_rll_l3(RSL_MT_DATA_IND, mctx, msg);
- } else {
- /* create rcv_buffer */
- if (!dl->rcv_buffer) {
- LOGP(DLLAPDM, LOGL_INFO, "message in multiple I "
- "frames (first message)\n");
- dl->rcv_buffer = msgb_alloc_headroom(200+56, 56,
- "LAPDm RX");
- dl->rcv_buffer->l3h = dl->rcv_buffer->data;
- }
- /* concat. rcv_buffer */
- if (msgb_l3len(dl->rcv_buffer) + length > 200) {
- LOGP(DLLAPDM, LOGL_NOTICE, "Received frame "
- "overflow!\n");
- } else {
- memcpy(msgb_put(dl->rcv_buffer, length),
- msg->l2h + 3, length);
- }
- /* if the last segment was received */
- if (!(msg->l2h[2] & LAPDm_MORE)) {
- LOGP(DLLAPDM, LOGL_INFO, "message in multiple I "
- "frames (last message)\n");
- rc = send_rslms_rll_l3(RSL_MT_DATA_IND, mctx,
- dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- } else
- LOGP(DLLAPDM, LOGL_INFO, "message in multiple I "
- "frames (next message)\n");
- msgb_free(msg);
-
- }
- } else
- LOGP(DLLAPDM, LOGL_INFO, "I frame ignored during own receiver "
- "busy condition\n");
-
- /* Check for P bit */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- /* 5.5.2.1 */
- /* check if we are not in own receiver busy */
- if (!dl->own_busy) {
- LOGP(DLLAPDM, LOGL_INFO, "we are not busy, send RR\n");
- /* Send RR with F=1 */
- rc = lapdm_send_rr(mctx, 1);
- } else {
- LOGP(DLLAPDM, LOGL_INFO, "we are busy, send RNR\n");
- /* Send RNR with F=1 */
- rc = lapdm_send_rnr(mctx, 1);
- }
- } else {
- /* 5.5.2.2 */
- /* check if we are not in own receiver busy */
- if (!dl->own_busy) {
- /* NOTE: V(R) is already set above */
- rc = rslms_send_i(mctx, __LINE__);
- if (rc) {
- LOGP(DLLAPDM, LOGL_INFO, "we are not busy and "
- "have no pending data, send RR\n");
- /* Send RR with F=0 */
- return lapdm_send_rr(mctx, 0);
- }
- /* all I or one RR is sent, we are done */
- return 0;
- } else {
- LOGP(DLLAPDM, LOGL_INFO, "we are busy, send RNR\n");
- /* Send RNR with F=0 */
- rc = lapdm_send_rnr(mctx, 0);
- }
- }
-
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
- return rc;
-}
-/* Receive a LAPDm message from L1 */
-static int lapdm_ph_data_ind(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- int rc;
-
- /* G.2.3 EA bit set to "0" is not allowed in GSM */
- if (!LAPDm_ADDR_EA(mctx->addr)) {
- LOGP(DLLAPDM, LOGL_NOTICE, "EA bit 0 is not allowed in GSM\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- if (LAPDm_CTRL_is_U(mctx->ctrl))
- rc = lapdm_rx_u(msg, mctx);
- else if (LAPDm_CTRL_is_S(mctx->ctrl))
- rc = lapdm_rx_s(msg, mctx);
- else if (LAPDm_CTRL_is_I(mctx->ctrl))
- rc = lapdm_rx_i(msg, mctx);
- else {
- LOGP(DLLAPDM, LOGL_NOTICE, "unknown LAPDm format\n");
- msgb_free(msg);
- rc = -EINVAL;
- }
- return rc;
+ return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
+ 23);
}
/* input into layer2 (from layer 1) */
-static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t chan_nr, uint8_t link_id)
+static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le,
+ uint8_t chan_nr, uint8_t link_id)
{
uint8_t cbits = chan_nr >> 3;
uint8_t sapi; /* we cannot take SAPI from link_id, as L1 has no clue */
struct lapdm_msg_ctx mctx;
+ struct lapd_msg_ctx lctx;
int rc = 0;
+ int n201;
/* when we reach here, we have a msgb with l2h pointing to the raw
* 23byte mac block. The l1h has already been purged. */
+ memset(&mctx, 0, sizeof(mctx));
mctx.chan_nr = chan_nr;
mctx.link_id = link_id;
- mctx.addr = mctx.ctrl = 0;
/* check for L1 chan_nr/link_id and determine LAPDm hdr format */
if (cbits == 0x10 || cbits == 0x12) {
/* Format Bbis is used on BCCH and CCCH(PCH, NCH and AGCH) */
mctx.lapdm_fmt = LAPDm_FMT_Bbis;
- mctx.n201 = N201_Bbis;
+ n201 = N201_Bbis;
sapi = 0;
} else {
if (mctx.link_id & 0x40) {
/* It was received from network on SACCH */
- /* If sent by BTS, lapdm_fmt must be B4 */
- if (le->mode == LAPDM_MODE_MS) {
+ /* If UI on SACCH sent by BTS, lapdm_fmt must be B4 */
+ if (le->mode == LAPDM_MODE_MS
+ && LAPDm_CTRL_is_U(msg->l2h[3])
+ && LAPDm_CTRL_U_BITS(msg->l2h[3]) == 0) {
mctx.lapdm_fmt = LAPDm_FMT_B4;
- mctx.n201 = N201_B4;
- LOGP(DLLAPDM, LOGL_INFO, "fmt=B4\n");
+ n201 = N201_B4;
+ LOGP(DLLAPD, LOGL_INFO, "fmt=B4\n");
} else {
mctx.lapdm_fmt = LAPDm_FMT_B;
- mctx.n201 = N201_AB_SACCH;
- LOGP(DLLAPDM, LOGL_INFO, "fmt=B\n");
+ n201 = N201_AB_SACCH;
+ LOGP(DLLAPD, LOGL_INFO, "fmt=B\n");
}
/* SACCH frames have a two-byte L1 header that
* OsmocomBB L1 doesn't strip */
@@ -1647,8 +541,8 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t cha
sapi = (msg->l2h[0] >> 2) & 7;
} else {
mctx.lapdm_fmt = LAPDm_FMT_B;
- LOGP(DLLAPDM, LOGL_INFO, "fmt=B\n");
- mctx.n201 = 23; // FIXME: select correct size by chan.
+ LOGP(DLLAPD, LOGL_INFO, "fmt=B\n");
+ n201 = N201_AB_SDCCH;
sapi = (msg->l2h[0] >> 2) & 7;
}
}
@@ -1656,7 +550,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t cha
mctx.dl = datalink_for_sapi(le, sapi);
/* G.2.1 No action on frames containing an unallocated SAPI. */
if (!mctx.dl) {
- LOGP(DLLAPDM, LOGL_NOTICE, "Received frame for unsupported "
+ LOGP(DLLAPD, LOGL_NOTICE, "Received frame for unsupported "
"SAPI %d!\n", sapi);
msgb_free(msg);
return -EIO;
@@ -1666,17 +560,77 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t cha
case LAPDm_FMT_A:
case LAPDm_FMT_B:
case LAPDm_FMT_B4:
- mctx.addr = msg->l2h[0];
- if (!(mctx.addr & 0x01)) {
- LOGP(DLLAPDM, LOGL_ERROR, "we don't support "
- "multibyte addresses (discarding)\n");
+ lctx.dl = &mctx.dl->dl;
+ /* obtain SAPI from address field */
+ mctx.link_id |= LAPDm_ADDR_SAPI(msg->l2h[0]);
+ /* G.2.3 EA bit set to "0" is not allowed in GSM */
+ if (!LAPDm_ADDR_EA(msg->l2h[0])) {
+ LOGP(DLLAPD, LOGL_NOTICE, "EA bit 0 is not allowed in "
+ "GSM\n");
msgb_free(msg);
+ rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, &mctx);
return -EINVAL;
}
- mctx.ctrl = msg->l2h[1];
- /* obtain SAPI from address field */
- mctx.link_id |= LAPDm_ADDR_SAPI(mctx.addr);
- rc = lapdm_ph_data_ind(msg, &mctx);
+ /* adress field */
+ lctx.lpd = LAPDm_ADDR_LPD(msg->l2h[0]);
+ lctx.sapi = LAPDm_ADDR_SAPI(msg->l2h[0]);
+ lctx.cr = LAPDm_ADDR_CR(msg->l2h[0]);
+ /* command field */
+ if (LAPDm_CTRL_is_I(msg->l2h[1])) {
+ lctx.format = LAPD_FORM_I;
+ lctx.n_send = LAPDm_CTRL_I_Ns(msg->l2h[1]);
+ lctx.n_recv = LAPDm_CTRL_Nr(msg->l2h[1]);
+ } else if (LAPDm_CTRL_is_S(msg->l2h[1])) {
+ lctx.format = LAPD_FORM_S;
+ lctx.n_recv = LAPDm_CTRL_Nr(msg->l2h[1]);
+ lctx.s_u = LAPDm_CTRL_S_BITS(msg->l2h[1]);
+ } else if (LAPDm_CTRL_is_U(msg->l2h[1])) {
+ lctx.format = LAPD_FORM_U;
+ lctx.s_u = LAPDm_CTRL_U_BITS(msg->l2h[1]);
+ } else
+ lctx.format = LAPD_FORM_UKN;
+ lctx.p_f = LAPDm_CTRL_PF_BIT(msg->l2h[1]);
+ if (lctx.sapi != LAPDm_SAPI_NORMAL
+ && lctx.sapi != LAPDm_SAPI_SMS
+ && lctx.format == LAPD_FORM_U
+ && lctx.s_u == LAPDm_U_UI) {
+ /* 5.3.3 UI frames with invalid SAPI values shall be
+ * discarded
+ */
+ LOGP(DLLAPD, LOGL_INFO, "sapi=%u (discarding)\n",
+ lctx.sapi);
+ msgb_free(msg);
+ return 0;
+ }
+ if (mctx.lapdm_fmt == LAPDm_FMT_B4) {
+ lctx.n201 = n201;
+ lctx.length = n201;
+ lctx.more = 0;
+ msg->l3h = msg->l2h + 2;
+ msgb_pull_l2h(msg);
+ } else {
+ /* length field */
+ if (!(msg->l2h[2] & LAPDm_EL)) {
+ /* G.4.1 If the EL bit is set to "0", an
+ * MDL-ERROR-INDICATION primitive with cause
+ * "frame not implemented" is sent to the
+ * mobile management entity. */
+ LOGP(DLLAPD, LOGL_NOTICE, "we don't support "
+ "multi-octet length\n");
+ msgb_free(msg);
+ rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, &mctx);
+ return -EINVAL;
+ }
+ lctx.n201 = n201;
+ lctx.length = msg->l2h[2] >> 2;
+ lctx.more = !!(msg->l2h[2] & LAPDm_MORE);
+ msg->l3h = msg->l2h + 3;
+ msgb_pull_l2h(msg);
+ }
+ /* store context for messages from lapd */
+ memcpy(&mctx.dl->mctx, &mctx, sizeof(mctx.dl->mctx));
+ /* send to LAPD */
+ rc = lapd_ph_data_ind(msg, &lctx);
break;
case LAPDm_FMT_Bter:
/* FIXME */
@@ -1684,7 +638,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t cha
break;
case LAPDm_FMT_Bbis:
/* directly pass up to layer3 */
- LOGP(DLLAPDM, LOGL_INFO, "fmt=Bbis UI\n");
+ LOGP(DLLAPD, LOGL_INFO, "fmt=Bbis UI\n");
msg->l3h = msg->l2h;
msgb_pull_l2h(msg);
rc = send_rslms_rll_l3(RSL_MT_UNIT_DATA_IND, &mctx, msg);
@@ -1732,7 +686,7 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
int rc = 0;
if (oph->sap != SAP_GSM_PH) {
- LOGP(DLLAPDM, LOGL_ERROR, "primitive for unknown SAP %u\n",
+ LOGP(DLLAPD, LOGL_ERROR, "primitive for unknown SAP %u\n",
oph->sap);
return -ENODEV;
}
@@ -1740,7 +694,7 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
switch (oph->primitive) {
case PRIM_PH_DATA:
if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DLLAPDM, LOGL_ERROR, "PH_DATA is not INDICATION %u\n",
+ LOGP(DLLAPD, LOGL_ERROR, "PH_DATA is not INDICATION %u\n",
oph->operation);
return -ENODEV;
}
@@ -1749,7 +703,7 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
break;
case PRIM_PH_RTS:
if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DLLAPDM, LOGL_ERROR, "PH_RTS is not INDICATION %u\n",
+ LOGP(DLLAPD, LOGL_ERROR, "PH_RTS is not INDICATION %u\n",
oph->operation);
return -ENODEV;
}
@@ -1776,33 +730,44 @@ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
/* L3 -> L2 / RSLMS -> LAPDm */
+/* Set LAPDm context for established connection */
+static int set_lapdm_context(struct lapdm_datalink *dl, uint8_t chan_nr,
+ uint8_t link_id, int n201, uint8_t sapi)
+{
+ memset(&dl->mctx, 0, sizeof(dl->mctx));
+ dl->mctx.dl = dl;
+ dl->mctx.chan_nr = chan_nr;
+ dl->mctx.link_id = link_id;
+ dl->dl.lctx.dl = &dl->dl;
+ dl->dl.lctx.n201 = n201;
+ dl->dl.lctx.sapi = sapi;
+
+ return 0;
+}
+
/* L3 requests establishment of data link */
static int rslms_rx_rll_est_req(struct msgb *msg, struct lapdm_datalink *dl)
{
- struct lapdm_entity *le = dl->entity;
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
uint8_t chan_nr = rllh->chan_nr;
uint8_t link_id = rllh->link_id;
uint8_t sapi = rllh->link_id & 7;
struct tlv_parsed tv;
uint8_t length;
- uint8_t n201 = 23; //FIXME
+ uint8_t n201 = (rllh->link_id & 0x40) ? N201_AB_SACCH : N201_AB_SDCCH;
+ struct osmo_dlsap_prim dp;
- /* Set chan_nr and link_id for established connection */
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.n201 = n201;
- dl->mctx.chan_nr = chan_nr;
- dl->mctx.link_id = link_id;
+ /* Set LAPDm context for established connection */
+ set_lapdm_context(dl, chan_nr, link_id, n201, sapi);
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
+ rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
if (TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- msg->l3h = TLVP_VAL(&tv, RSL_IE_L3_INFO);
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
/* contention resolution establishment procedure */
if (sapi != 0) {
/* According to clause 6, the contention resolution
* procedure is only permitted with SAPI value 0 */
- LOGP(DLLAPDM, LOGL_ERROR, "SAPI != 0 but contention"
+ LOGP(DLLAPD, LOGL_ERROR, "SAPI != 0 but contention"
"resolution (discarding)\n");
msgb_free(msg);
return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
@@ -1810,112 +775,89 @@ static int rslms_rx_rll_est_req(struct msgb *msg, struct lapdm_datalink *dl)
/* transmit a SABM command with the P bit set to "1". The SABM
* command shall contain the layer 3 message unit */
length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- LOGP(DLLAPDM, LOGL_INFO, "perform establishment with content "
- "(SABM)\n");
} else {
/* normal establishment procedure */
+ msg->l3h = msg->l2h + sizeof(*rllh);
length = 0;
- LOGP(DLLAPDM, LOGL_INFO, "perform normal establishm. (SABM)\n");
}
/* check if the layer3 message length exceeds N201 */
- if (length + 3 > 21) { /* FIXME: do we know the channel N201? */
- LOGP(DLLAPDM, LOGL_ERROR, "frame too large: %d > N201(%d) "
- "(discarding)\n", length + 3, 21);
+ if (length > n201) {
+ LOGP(DLLAPD, LOGL_ERROR, "frame too large: %d > N201(%d) "
+ "(discarding)\n", length, n201);
msgb_free(msg);
return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
}
- /* Flush send-queue */
- /* Clear send-buffer */
- lapdm_dl_flush_send(dl);
-
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
-
- /* Remove RLL header from msgb */
+ /* Remove RLL header from msgb and set length to L3-info */
msgb_pull_l2h(msg);
+ msg->len = length;
+ msg->tail = msg->l3h + length;
- /* Push LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_SABM, 1);
- msg->l2h[2] = LAPDm_LEN(length);
- /* Transmit-buffer carries exactly one segment */
- memcpy(dl->tx_hist[0], msg->l2h, 3 + length);
- dl->tx_length[0] = 3 + length;
- /* set Vs to 0, because it is used as index when resending SABM */
- dl->V_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_SABM_SENT);
-
- /* Tramsmit and start T200 */
- osmo_timer_schedule(&dl->t200, T200);
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, n201);
+ /* prepare prim */
+ osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
+
+ /* send to L2 */
+ return lapd_recv_dlsap(&dp, &dl->dl.lctx);
}
/* L3 requests transfer of unnumbered information */
static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
{
struct lapdm_entity *le = dl->entity;
+ int ui_bts = (le->mode == LAPDM_MODE_BTS);
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
uint8_t chan_nr = rllh->chan_nr;
uint8_t link_id = rllh->link_id;
uint8_t sapi = link_id & 7;
struct tlv_parsed tv;
int length;
- uint8_t n201 = 23; //FIXME
- uint8_t ta = 0, tx_power = 0;
/* check if the layer3 message length exceeds N201 */
rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
if (TLVP_PRESENT(&tv, RSL_IE_TIMING_ADVANCE)) {
- ta = *TLVP_VAL(&tv, RSL_IE_TIMING_ADVANCE);
+ le->ta = *TLVP_VAL(&tv, RSL_IE_TIMING_ADVANCE);
}
if (TLVP_PRESENT(&tv, RSL_IE_MS_POWER)) {
- tx_power = *TLVP_VAL(&tv, RSL_IE_MS_POWER);
+ le->tx_power = *TLVP_VAL(&tv, RSL_IE_MS_POWER);
}
if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLLAPDM, LOGL_ERROR, "unit data request without message "
+ LOGP(DLLAPD, LOGL_ERROR, "unit data request without message "
"error\n");
msgb_free(msg);
return -EINVAL;
}
- msg->l3h = TLVP_VAL(&tv, RSL_IE_L3_INFO);
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
/* check if the layer3 message length exceeds N201 */
- if (length + 5 > 23) { /* FIXME: do we know the channel N201? */
- LOGP(DLLAPDM, LOGL_ERROR, "frame too large: %d > N201(%d) "
- "(discarding)\n", length + 5, 23);
+ if (length + 4 + !ui_bts > 23) {
+ LOGP(DLLAPD, LOGL_ERROR, "frame too large: %d > N201(%d) "
+ "(discarding)\n", length, 18 + ui_bts);
msgb_free(msg);
return -EIO;
}
- LOGP(DLLAPDM, LOGL_INFO, "sending unit data (tx_power=%d, ta=%d)\n",
- tx_power, ta);
+ LOGP(DLLAPD, LOGL_INFO, "sending unit data (tx_power=%d, ta=%d)\n",
+ le->tx_power, le->ta);
- /* Remove RLL header from msgb */
+ /* Remove RLL header from msgb and set length to L3-info */
msgb_pull_l2h(msg);
+ msg->len = length;
+ msg->tail = msg->l3h + length;
/* Push L1 + LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 2 + 3);
- msg->l2h[0] = tx_power;
- msg->l2h[1] = ta;
- msg->l2h[2] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
+ msg->l2h = msgb_push(msg, 4 + !ui_bts);
+ msg->l2h[0] = le->tx_power;
+ msg->l2h[1] = le->ta;
+ msg->l2h[2] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, dl->dl.cr.loc2rem.cmd);
msg->l2h[3] = LAPDm_CTRL_U(LAPDm_U_UI, 0);
- msg->l2h[4] = LAPDm_LEN(length);
- // FIXME: short L2 header support
+ if (!ui_bts)
+ msg->l2h[4] = LAPDm_LEN(length);
/* Tramsmit */
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, n201);
+ return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, 23);
}
/* L3 requests transfer of acknowledged information */
@@ -1923,143 +865,29 @@ static int rslms_rx_rll_data_req(struct msgb *msg, struct lapdm_datalink *dl)
{
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
struct tlv_parsed tv;
+ int length;
+ struct osmo_dlsap_prim dp;
rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLLAPDM, LOGL_ERROR, "data request without message "
+ LOGP(DLLAPD, LOGL_ERROR, "data request without message "
"error\n");
msgb_free(msg);
return -EINVAL;
}
- msg->l3h = TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- LOGP(DLLAPDM, LOGL_INFO, "writing message to send-queue\n");
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
+ length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- /* Remove the RSL/RLL header */
+ /* Remove RLL header from msgb and set length to L3-info */
msgb_pull_l2h(msg);
+ msg->len = length;
+ msg->tail = msg->l3h + length;
- /* Write data into the send queue */
- msgb_enqueue(&dl->send_queue, msg);
+ /* prepare prim */
+ osmo_prim_init(&dp.oph, 0, PRIM_DL_DATA, PRIM_OP_REQUEST, msg);
- /* Send message, if possible */
- rslms_send_i(&dl->mctx, __LINE__);
- return 0;
-}
-
-/* Send next I frame from queued/buffered data */
-static int rslms_send_i(struct lapdm_msg_ctx *mctx, int line)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- uint8_t chan_nr = mctx->chan_nr;
- uint8_t link_id = mctx->link_id;
- uint8_t sapi = link_id & 7;
- int k = k_sapi[sapi];
- struct msgb *msg;
- int length, left;
- int rc = - 1; /* we sent nothing */
-
- LOGP(DLLAPDM, LOGL_INFO, "%s() called from line %d\n", __func__, line);
-
- next_frame:
-
- if (dl->peer_busy) {
- LOGP(DLLAPDM, LOGL_INFO, "peer busy, not sending\n");
- return rc;
- }
-
- if (dl->state == LAPDm_STATE_TIMER_RECOV) {
- LOGP(DLLAPDM, LOGL_INFO, "timer recovery, not sending\n");
- return rc;
- }
-
- /* If the send state variable V(S) is equal to V(A) plus k
- * (where k is the maximum number of outstanding I frames - see
- * subclause 5.8.4), the data link layer entity shall not transmit any
- * new I frames, but shall retransmit an I frame as a result
- * of the error recovery procedures as described in subclauses 5.5.4 and
- * 5.5.7. */
- if (dl->V_send == add_mod8(dl->V_ack, k)) {
- LOGP(DLLAPDM, LOGL_INFO, "k frames outstanding, not sending "
- "more (k=%u V(S)=%u V(A)=%u)\n", k, dl->V_send,
- dl->V_ack);
- return rc;
- }
-
- /* if we have no tx_hist yet, we create it */
- if (!dl->tx_length[dl->V_send]) {
- /* Get next message into send-buffer, if any */
- if (!dl->send_buffer) {
- next_message:
- dl->send_out = 0;
- dl->send_buffer = msgb_dequeue(&dl->send_queue);
- /* No more data to be sent */
- if (!dl->send_buffer)
- return rc;
- LOGP(DLLAPDM, LOGL_INFO, "get message from "
- "send-queue\n");
- }
-
- /* How much is left in the send-buffer? */
- left = msgb_l3len(dl->send_buffer) - dl->send_out;
- /* Segment, if data exceeds N201 */
- length = left;
- if (length > mctx->n201 - 3)
- length = mctx->n201 - 3;
- LOGP(DLLAPDM, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
- "length %d first byte %02x\n",
- msgb_l3len(dl->send_buffer), dl->send_out, left,
- mctx->n201, length, dl->send_buffer->l3h[0]);
- /* If message in send-buffer is completely sent */
- if (left == 0) {
- msgb_free(dl->send_buffer);
- dl->send_buffer = NULL;
- goto next_message;
- }
-
- LOGP(DLLAPDM, LOGL_INFO, "send I frame %sV(S)=%d\n",
- (left > length) ? "segment " : "", dl->V_send);
-
- /* Create I frame (segment) and transmit-buffer content */
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm I");
- msg->l2h = msgb_put(msg, 3 + length);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_I(dl->V_recv, dl->V_send, 0);
- msg->l2h[2] = LAPDm_LEN(length);
- if (left > length)
- msg->l2h[2] |= LAPDm_MORE;
- memcpy(msg->l2h + 3, dl->send_buffer->l3h + dl->send_out,
- length);
- memcpy(dl->tx_hist[dl->V_send], msg->l2h, 3 + length);
- dl->tx_length[dl->V_send] = 3 + length;
- /* Add length to track how much is already in the tx buffer */
- dl->send_out += length;
- } else {
- LOGP(DLLAPDM, LOGL_INFO, "resend I frame from tx buffer "
- "V(S)=%d\n", dl->V_send);
-
- /* Create I frame (segment) from tx_hist */
- length = dl->tx_length[dl->V_send];
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm I");
- msg->l2h = msgb_put(msg, length);
- memcpy(msg->l2h, dl->tx_hist[dl->V_send], length);
- msg->l2h[1] = LAPDm_CTRL_I(dl->V_recv, dl->V_send, 0);
- }
-
- /* The value of the send state variable V(S) shall be incremented by 1
- * at the end of the transmission of the I frame */
- dl->V_send = inc_mod8(dl->V_send);
-
- /* If timer T200 is not running at the time right before transmitting a
- * frame, when the PH-READY-TO-SEND primitive is received from the
- * physical layer., it shall be set. */
- if (!osmo_timer_pending(&dl->t200))
- osmo_timer_schedule(&dl->t200, T200);
-
- tx_ph_data_enqueue(dl, msg, chan_nr, link_id, mctx->n201);
-
- rc = 0; /* we sent something */
- goto next_frame;
+ /* send to L2 */
+ return lapd_recv_dlsap(&dp, &dl->dl.lctx);
}
/* L3 requests suspension of data link */
@@ -2067,165 +895,79 @@ static int rslms_rx_rll_susp_req(struct msgb *msg, struct lapdm_datalink *dl)
{
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
uint8_t sapi = rllh->link_id & 7;
+ struct osmo_dlsap_prim dp;
if (sapi != 0) {
- LOGP(DLLAPDM, LOGL_ERROR, "SAPI != 0 while suspending\n");
+ LOGP(DLLAPD, LOGL_ERROR, "SAPI != 0 while suspending\n");
msgb_free(msg);
return -EINVAL;
}
- LOGP(DLLAPDM, LOGL_INFO, "perform suspension\n");
-
- /* put back the send-buffer to the send-queue (first position) */
- if (dl->send_buffer) {
- LOGP(DLLAPDM, LOGL_INFO, "put frame in sendbuffer back to "
- "queue\n");
- llist_add(&dl->send_buffer->list, &dl->send_queue);
- dl->send_buffer = NULL;
- } else
- LOGP(DLLAPDM, LOGL_INFO, "no frame in sendbuffer\n");
-
- /* Clear transmit buffer, but keep send buffer */
- lapdm_dl_flush_tx(dl);
-
- msgb_free(msg);
+ /* prepare prim */
+ osmo_prim_init(&dp.oph, 0, PRIM_DL_SUSP, PRIM_OP_REQUEST, msg);
- return send_rll_simple(RSL_MT_SUSP_CONF, &dl->mctx);
+ /* send to L2 */
+ return lapd_recv_dlsap(&dp, &dl->dl.lctx);
}
/* L3 requests resume of data link */
static int rslms_rx_rll_res_req(struct msgb *msg, struct lapdm_datalink *dl)
{
- struct lapdm_entity *le = dl->entity;
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ int msg_type = rllh->c.msg_type;
uint8_t chan_nr = rllh->chan_nr;
uint8_t link_id = rllh->link_id;
uint8_t sapi = rllh->link_id & 7;
struct tlv_parsed tv;
uint8_t length;
- uint8_t n201 = 23; //FIXME
+ uint8_t n201 = (rllh->link_id & 0x40) ? N201_AB_SACCH : N201_AB_SDCCH;
+ struct osmo_dlsap_prim dp;
- /* Set chan_nr and link_id for established connection */
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.n201 = n201;
- dl->mctx.chan_nr = chan_nr;
- dl->mctx.link_id = link_id;
+ /* Set LAPDm context for established connection */
+ set_lapdm_context(dl, chan_nr, link_id, n201, sapi);
rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLLAPDM, LOGL_ERROR, "resume without message error\n");
+ LOGP(DLLAPD, LOGL_ERROR, "resume without message error\n");
msgb_free(msg);
return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
}
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- LOGP(DLLAPDM, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
- length);
-
- /* Replace message in the send-buffer (reconnect) */
- if (dl->send_buffer)
- msgb_free(dl->send_buffer);
- dl->send_out = 0;
- if (length) {
- /* Remove the RSL/RLL header */
- msgb_pull_l2h(msg);
- /* Write data into the send buffer, to be sent first */
- dl->send_buffer = msg;
- }
+ /* Remove RLL header from msgb and set length to L3-info */
+ msgb_pull_l2h(msg);
+ msg->len = length;
+ msg->tail = msg->l3h + length;
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
+ /* prepare prim */
+ osmo_prim_init(&dp.oph, 0, (msg_type == RSL_MT_RES_REQ) ? PRIM_DL_RES
+ : PRIM_DL_RECON, PRIM_OP_REQUEST, msg);
- /* Create new msgb (old one is now free) */
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm SABM");
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_SABM, 1);
- msg->l2h[2] = LAPDm_LEN(0);
- /* Transmit-buffer carries exactly one segment */
- memcpy(dl->tx_hist[0], msg->l2h, 3);
- dl->tx_length[0] = 3;
- /* set Vs to 0, because it is used as index when resending SABM */
- dl->V_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_SABM_SENT);
-
- /* Tramsmit and start T200 */
- osmo_timer_schedule(&dl->t200, T200);
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, n201);
+ /* send to L2 */
+ return lapd_recv_dlsap(&dp, &dl->dl.lctx);
}
/* L3 requests release of data link */
static int rslms_rx_rll_rel_req(struct msgb *msg, struct lapdm_datalink *dl)
{
- struct lapdm_entity *le = dl->entity;
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = rllh->link_id & 7;
uint8_t mode = 0;
+ struct osmo_dlsap_prim dp;
/* get release mode */
if (rllh->data[0] == RSL_IE_RELEASE_MODE)
mode = rllh->data[1] & 1;
- /* local release */
- if (mode) {
- LOGP(DLLAPDM, LOGL_INFO, "perform local release\n");
- msgb_free(msg);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* enter idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* flush buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* send notification to L3 */
- return send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
- }
-
- /* in case we are already disconnecting */
- if (dl->state == LAPDm_STATE_DISC_SENT)
- return -EBUSY;
-
- LOGP(DLLAPDM, LOGL_INFO, "perform normal release (DISC)\n");
-
/* Pull rllh */
msgb_pull(msg, msg->tail - msg->l2h);
- /* Push LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_DISC, 1);
- msg->l2h[2] = LAPDm_LEN(0);
- /* Transmit-buffer carries exactly one segment */
- memcpy(dl->tx_hist[0], msg->l2h, 3);
- dl->tx_length[0] = 3;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_DISC_SENT);
-
- /* Tramsmit and start T200 */
- osmo_timer_schedule(&dl->t200, T200);
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, dl->mctx.n201);
-}
+ /* prepare prim */
+ osmo_prim_init(&dp.oph, 0, PRIM_DL_REL, PRIM_OP_REQUEST, msg);
+ dp.u.rel_req.mode = mode;
-/* L3 requests release in idle state */
-static int rslms_rx_rll_rel_req_idle(struct msgb *msg, struct lapdm_datalink *dl)
-{
- msgb_free(msg);
-
- /* send notification to L3 */
- return send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
+ /* send to L2 */
+ return lapd_recv_dlsap(&dp, &dl->dl.lctx);
}
/* L3 requests channel in idle state */
@@ -2239,11 +981,11 @@ static int rslms_rx_chan_rqd(struct lapdm_channel *lc, struct msgb *msg)
PRIM_OP_REQUEST, NULL);
if (msgb_l2len(msg) < sizeof(*cch) + 4 + 2 + 2) {
- LOGP(DLLAPDM, LOGL_ERROR, "Message too short for CHAN RQD!\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Message too short for CHAN RQD!\n");
return -EINVAL;
}
if (cch->data[0] != RSL_IE_REQ_REFERENCE) {
- LOGP(DLLAPDM, LOGL_ERROR, "Missing REQ REFERENCE IE\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Missing REQ REFERENCE IE\n");
return -EINVAL;
}
pp.u.rach_req.ra = cch->data[1];
@@ -2251,14 +993,14 @@ static int rslms_rx_chan_rqd(struct lapdm_channel *lc, struct msgb *msg)
pp.u.rach_req.is_combined_ccch = cch->data[2] >> 7;
if (cch->data[4] != RSL_IE_ACCESS_DELAY) {
- LOGP(DLLAPDM, LOGL_ERROR, "Missing ACCESS_DELAY IE\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Missing ACCESS_DELAY IE\n");
return -EINVAL;
}
/* TA = 0 - delay */
pp.u.rach_req.ta = 0 - cch->data[5];
if (cch->data[6] != RSL_IE_MS_POWER) {
- LOGP(DLLAPDM, LOGL_ERROR, "Missing MS POWER IE\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Missing MS POWER IE\n");
return -EINVAL;
}
pp.u.rach_req.tx_power = cch->data[7];
@@ -2292,65 +1034,6 @@ static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t f
return rslms_sendmsg(msg, le);
}
-const char *lapdm_state_names[] = {
- "LAPDm_STATE_NULL",
- "LAPDm_STATE_IDLE",
- "LAPDm_STATE_SABM_SENT",
- "LAPDm_STATE_MF_EST",
- "LAPDm_STATE_TIMER_RECOV",
- "LAPDm_STATE_DISC_SENT",
-};
-
-/* statefull handling for RSLms RLL messages from L3 */
-static struct l2downstate {
- uint32_t states;
- int type;
- int (*rout) (struct msgb *msg, struct lapdm_datalink *dl);
-} l2downstatelist[] = {
- /* create and send UI command */
- {ALL_STATES,
- RSL_MT_UNIT_DATA_REQ, rslms_rx_rll_udata_req},
-
- /* create and send SABM command */
- {SBIT(LAPDm_STATE_IDLE),
- RSL_MT_EST_REQ, rslms_rx_rll_est_req},
-
- /* create and send I command */
- {SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_DATA_REQ, rslms_rx_rll_data_req},
-
- /* suspend datalink */
- {SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_SUSP_REQ, rslms_rx_rll_susp_req},
-
- /* create and send SABM command (resume) */
- {SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_RES_REQ, rslms_rx_rll_res_req},
-
- /* create and send SABM command (reconnect) */
- {SBIT(LAPDm_STATE_IDLE) |
- SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_RECON_REQ, rslms_rx_rll_res_req},
-
- /* create and send DISC command */
- {SBIT(LAPDm_STATE_SABM_SENT) |
- SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV) |
- SBIT(LAPDm_STATE_DISC_SENT),
- RSL_MT_REL_REQ, rslms_rx_rll_rel_req},
-
- /* release in idle state */
- {SBIT(LAPDm_STATE_IDLE),
- RSL_MT_REL_REQ, rslms_rx_rll_rel_req_idle},
-};
-
-#define L2DOWNSLLEN \
- (sizeof(l2downstatelist) / sizeof(struct l2downstate))
-
/* incoming RSLms RLL message from L3 */
static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc)
{
@@ -2359,11 +1042,11 @@ static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc)
uint8_t sapi = rllh->link_id & 7;
struct lapdm_entity *le;
struct lapdm_datalink *dl;
- int i, supported = 0;
int rc = 0;
if (msgb_l2len(msg) < sizeof(*rllh)) {
- LOGP(DLLAPDM, LOGL_ERROR, "Message too short for RLL hdr!\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Message too short for RLL hdr!\n");
+ msgb_free(msg);
return -EINVAL;
}
@@ -2377,34 +1060,42 @@ static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc)
*/
dl = datalink_for_sapi(le, sapi);
if (!dl) {
- LOGP(DLLAPDM, LOGL_ERROR, "No instance for SAPI %d!\n", sapi);
+ LOGP(DLLAPD, LOGL_ERROR, "No instance for SAPI %d!\n", sapi);
+ msgb_free(msg);
return -EINVAL;
}
- LOGP(DLLAPDM, LOGL_INFO, "(%p) RLL Message '%s' received in state %s\n",
- lc->name, rsl_msg_name(msg_type), lapdm_state_names[dl->state]);
+ LOGP(DLLAPD, LOGL_INFO, "(%p) RLL Message '%s' received. (sapi %d)\n",
+ lc->name, rsl_msg_name(msg_type), sapi);
- /* find function for current state and message */
- for (i = 0; i < L2DOWNSLLEN; i++) {
- if (msg_type == l2downstatelist[i].type)
- supported = 1;
- if ((msg_type == l2downstatelist[i].type)
- && ((1 << dl->state) & l2downstatelist[i].states))
- break;
- }
- if (!supported) {
- LOGP(DLLAPDM, LOGL_NOTICE, "Message unsupported.\n");
- msgb_free(msg);
- return 0;
- }
- if (i == L2DOWNSLLEN) {
- LOGP(DLLAPDM, LOGL_NOTICE, "Message unhandled at this state.\n");
+ switch (msg_type) {
+ case RSL_MT_UNIT_DATA_REQ:
+ rc = rslms_rx_rll_udata_req(msg, dl);
+ break;
+ case RSL_MT_EST_REQ:
+ rc = rslms_rx_rll_est_req(msg, dl);
+ break;
+ case RSL_MT_DATA_REQ:
+ rc = rslms_rx_rll_data_req(msg, dl);
+ break;
+ case RSL_MT_SUSP_REQ:
+ rc = rslms_rx_rll_susp_req(msg, dl);
+ break;
+ case RSL_MT_RES_REQ:
+ rc = rslms_rx_rll_res_req(msg, dl);
+ break;
+ case RSL_MT_RECON_REQ:
+ rc = rslms_rx_rll_res_req(msg, dl);
+ break;
+ case RSL_MT_REL_REQ:
+ rc = rslms_rx_rll_rel_req(msg, dl);
+ break;
+ default:
+ LOGP(DLLAPD, LOGL_NOTICE, "Message unsupported.\n");
msgb_free(msg);
- return 0;
+ rc = -EINVAL;
}
- rc = l2downstatelist[i].rout(msg, dl);
-
return rc;
}
@@ -2416,7 +1107,7 @@ static int rslms_rx_com_chan(struct msgb *msg, struct lapdm_channel *lc)
int rc = 0;
if (msgb_l2len(msg) < sizeof(*cch)) {
- LOGP(DLLAPDM, LOGL_ERROR, "Message too short for COM CHAN hdr!\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Message too short for COM CHAN hdr!\n");
return -EINVAL;
}
@@ -2426,7 +1117,7 @@ static int rslms_rx_com_chan(struct msgb *msg, struct lapdm_channel *lc)
rc = rslms_rx_chan_rqd(lc, msg);
break;
default:
- LOGP(DLLAPDM, LOGL_NOTICE, "Unknown COMMON CHANNEL msg %d!\n",
+ LOGP(DLLAPD, LOGL_NOTICE, "Unknown COMMON CHANNEL msg %d!\n",
msg_type);
msgb_free(msg);
return 0;
@@ -2442,7 +1133,7 @@ int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc)
int rc = 0;
if (msgb_l2len(msg) < sizeof(*rslh)) {
- LOGP(DLLAPDM, LOGL_ERROR, "Message too short RSL hdr!\n");
+ LOGP(DLLAPD, LOGL_ERROR, "Message too short RSL hdr!\n");
return -EINVAL;
}
@@ -2454,7 +1145,7 @@ int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc)
rc = rslms_rx_com_chan(msg, lc);
break;
default:
- LOGP(DLLAPDM, LOGL_ERROR, "unknown RSLms message "
+ LOGP(DLLAPD, LOGL_ERROR, "unknown RSLms message "
"discriminator 0x%02x", rslh->msg_discr);
msgb_free(msg);
return -EINVAL;
@@ -2466,23 +1157,24 @@ int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc)
/*! \brief Set the \ref lapdm_mode of a LAPDm entity */
int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode)
{
+ int i;
+ enum lapd_mode lm;
+
switch (mode) {
case LAPDM_MODE_MS:
- le->cr.loc2rem.cmd = CR_MS2BS_CMD;
- le->cr.loc2rem.resp = CR_MS2BS_RESP;
- le->cr.rem2loc.cmd = CR_BS2MS_CMD;
- le->cr.rem2loc.resp = CR_BS2MS_RESP;
+ lm = LAPD_MODE_USER;
break;
case LAPDM_MODE_BTS:
- le->cr.loc2rem.cmd = CR_BS2MS_CMD;
- le->cr.loc2rem.resp = CR_BS2MS_RESP;
- le->cr.rem2loc.cmd = CR_MS2BS_CMD;
- le->cr.rem2loc.resp = CR_MS2BS_RESP;
+ lm = LAPD_MODE_NETWORK;
break;
default:
return -EINVAL;
}
+ for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
+ lapd_set_mode(&le->datalink[i].dl, lm);
+ }
+
le->mode = mode;
return 0;
@@ -2526,16 +1218,7 @@ void lapdm_entity_reset(struct lapdm_entity *le)
for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
dl = &le->datalink[i];
- if (dl->state == LAPDm_STATE_IDLE)
- continue;
- LOGP(DLLAPDM, LOGL_INFO, "Resetting LAPDm instance\n");
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* enter idle state */
- dl->state = LAPDm_STATE_IDLE;
- /* flush buffer */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
+ lapd_dl_reset(&dl->dl);
}
}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c
new file mode 100644
index 0000000..8f35caa
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c
@@ -0,0 +1,38 @@
+/*
+ * AES encrypt_block
+ *
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "aes.h"
+#include "aes_wrap.h"
+
+/**
+ * aes_128_encrypt_block - Perform one AES 128-bit block operation
+ * @key: Key for AES
+ * @in: Input data (16 bytes)
+ * @out: Output of the AES block operation (16 bytes)
+ * Returns: 0 on success, -1 on failure
+ */
+int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
+{
+ void *ctx;
+ ctx = aes_encrypt_init(key, 16);
+ if (ctx == NULL)
+ return -1;
+ aes_encrypt(ctx, in, out);
+ aes_encrypt_deinit(ctx);
+ return 0;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c
new file mode 100644
index 0000000..8726aa7
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c
@@ -0,0 +1,121 @@
+/*
+ * AES (Rijndael) cipher - encrypt
+ *
+ * Modifications to public domain implementation:
+ * - support only 128-bit keys
+ * - cleanup
+ * - use C pre-processor to make it easier to change S table access
+ * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
+ * cost of reduced throughput (quite small difference on Pentium 4,
+ * 10-25% when using -O1 or -O2 optimization)
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto.h"
+#include "aes_i.h"
+
+static void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16])
+{
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+ const int Nr = 10;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(pt ) ^ rk[0];
+ s1 = GETU32(pt + 4) ^ rk[1];
+ s2 = GETU32(pt + 8) ^ rk[2];
+ s3 = GETU32(pt + 12) ^ rk[3];
+
+#define ROUND(i,d,s) \
+d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
+d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
+d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
+d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
+
+#ifdef FULL_UNROLL
+
+ ROUND(1,t,s);
+ ROUND(2,s,t);
+ ROUND(3,t,s);
+ ROUND(4,s,t);
+ ROUND(5,t,s);
+ ROUND(6,s,t);
+ ROUND(7,t,s);
+ ROUND(8,s,t);
+ ROUND(9,t,s);
+
+ rk += Nr << 2;
+
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+ r = Nr >> 1;
+ for (;;) {
+ ROUND(1,t,s);
+ rk += 8;
+ if (--r == 0)
+ break;
+ ROUND(0,s,t);
+ }
+
+#endif /* ?FULL_UNROLL */
+
+#undef ROUND
+
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
+ PUTU32(ct , s0);
+ s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
+ PUTU32(ct + 4, s1);
+ s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
+ PUTU32(ct + 8, s2);
+ s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
+ PUTU32(ct + 12, s3);
+}
+
+
+void * aes_encrypt_init(const u8 *key, size_t len)
+{
+ u32 *rk;
+ if (len != 16)
+ return NULL;
+ rk = os_malloc(AES_PRIV_SIZE);
+ if (rk == NULL)
+ return NULL;
+ rijndaelKeySetupEnc(rk, key);
+ return rk;
+}
+
+
+void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
+{
+ rijndaelEncrypt(ctx, plain, crypt);
+}
+
+
+void aes_encrypt_deinit(void *ctx)
+{
+ os_memset(ctx, 0, AES_PRIV_SIZE);
+ os_free(ctx);
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal.c b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal.c
new file mode 100644
index 0000000..4161220
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes-internal.c
@@ -0,0 +1,805 @@
+/*
+ * AES (Rijndael) cipher
+ *
+ * Modifications to public domain implementation:
+ * - support only 128-bit keys
+ * - cleanup
+ * - use C pre-processor to make it easier to change S table access
+ * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
+ * cost of reduced throughput (quite small difference on Pentium 4,
+ * 10-25% when using -O1 or -O2 optimization)
+ *
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto.h"
+#include "aes_i.h"
+
+/*
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+const u32 Te0[256] = {
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+#ifndef AES_SMALL_TABLES
+const u32 Te1[256] = {
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+const u32 Te2[256] = {
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+const u32 Te3[256] = {
+
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+const u32 Te4[256] = {
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+#endif /* AES_SMALL_TABLES */
+const u32 Td0[256] = {
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+#ifndef AES_SMALL_TABLES
+const u32 Td1[256] = {
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+const u32 Td2[256] = {
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+const u32 Td3[256] = {
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+const u32 Td4[256] = {
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+const u32 rcon[] = {
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+#else /* AES_SMALL_TABLES */
+const u8 Td4s[256] = {
+ 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+ 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+ 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+ 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+ 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+ 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+ 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+ 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+ 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+ 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+ 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+ 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+ 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+ 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+ 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+ 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+ 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+ 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+ 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+ 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+ 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+ 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+ 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+ 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+ 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+ 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+ 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+ 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+ 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+ 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+ 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+ 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+const u8 rcons[] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
+ /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+#endif /* AES_SMALL_TABLES */
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
+{
+ int i;
+ u32 temp;
+
+ rk[0] = GETU32(cipherKey );
+ rk[1] = GETU32(cipherKey + 4);
+ rk[2] = GETU32(cipherKey + 8);
+ rk[3] = GETU32(cipherKey + 12);
+ for (i = 0; i < 10; i++) {
+ temp = rk[3];
+ rk[4] = rk[0] ^
+ TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
+ RCON(i);
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ rk += 4;
+ }
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes.h
new file mode 100644
index 0000000..ba384a9
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes.h
@@ -0,0 +1,27 @@
+/*
+ * AES functions
+ * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef AES_H
+#define AES_H
+
+#define AES_BLOCK_SIZE 16
+
+void * aes_encrypt_init(const u8 *key, size_t len);
+void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt);
+void aes_encrypt_deinit(void *ctx);
+void * aes_decrypt_init(const u8 *key, size_t len);
+void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain);
+void aes_decrypt_deinit(void *ctx);
+
+#endif /* AES_H */
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_i.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_i.h
new file mode 100644
index 0000000..6b40bc7
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_i.h
@@ -0,0 +1,122 @@
+/*
+ * AES (Rijndael) cipher
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef AES_I_H
+#define AES_I_H
+
+#include "aes.h"
+
+/* #define FULL_UNROLL */
+#define AES_SMALL_TABLES
+
+extern const u32 Te0[256];
+extern const u32 Te1[256];
+extern const u32 Te2[256];
+extern const u32 Te3[256];
+extern const u32 Te4[256];
+extern const u32 Td0[256];
+extern const u32 Td1[256];
+extern const u32 Td2[256];
+extern const u32 Td3[256];
+extern const u32 Td4[256];
+extern const u32 rcon[10];
+extern const u8 Td4s[256];
+extern const u8 rcons[10];
+
+#ifndef AES_SMALL_TABLES
+
+#define RCON(i) rcon[(i)]
+
+#define TE0(i) Te0[((i) >> 24) & 0xff]
+#define TE1(i) Te1[((i) >> 16) & 0xff]
+#define TE2(i) Te2[((i) >> 8) & 0xff]
+#define TE3(i) Te3[(i) & 0xff]
+#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
+#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
+#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
+#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
+#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
+#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
+#define TE4(i) (Te4[(i)] & 0x000000ff)
+
+#define TD0(i) Td0[((i) >> 24) & 0xff]
+#define TD1(i) Td1[((i) >> 16) & 0xff]
+#define TD2(i) Td2[((i) >> 8) & 0xff]
+#define TD3(i) Td3[(i) & 0xff]
+#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
+#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
+#define TD0_(i) Td0[(i) & 0xff]
+#define TD1_(i) Td1[(i) & 0xff]
+#define TD2_(i) Td2[(i) & 0xff]
+#define TD3_(i) Td3[(i) & 0xff]
+
+#else /* AES_SMALL_TABLES */
+
+#define RCON(i) (rcons[(i)] << 24)
+
+static inline u32 rotr(u32 val, int bits)
+{
+ return (val >> bits) | (val << (32 - bits));
+}
+
+#define TE0(i) Te0[((i) >> 24) & 0xff]
+#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
+#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
+#define TE3(i) rotr(Te0[(i) & 0xff], 24)
+#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
+#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
+#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
+#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
+#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
+#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
+#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
+#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
+#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
+
+#define TD0(i) Td0[((i) >> 24) & 0xff]
+#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
+#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
+#define TD3(i) rotr(Td0[(i) & 0xff], 24)
+#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
+#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
+#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
+#define TD44(i) (Td4s[(i) & 0xff])
+#define TD0_(i) Td0[(i) & 0xff]
+#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
+#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
+#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
+
+#endif /* AES_SMALL_TABLES */
+
+#ifdef _MSC_VER
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+#define GETU32(p) SWAP(*((u32 *)(p)))
+#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
+((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { \
+(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
+(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+#endif
+
+#define AES_PRIV_SIZE (4 * 44)
+
+void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[]);
+
+#endif /* AES_I_H */
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h
new file mode 100644
index 0000000..4b1c7b0
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h
@@ -0,0 +1,48 @@
+/*
+ * AES-based functions
+ *
+ * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
+ * - One-Key CBC MAC (OMAC1) hash with AES-128
+ * - AES-128 CTR mode encryption
+ * - AES-128 EAX mode encryption/decryption
+ * - AES-128 CBC
+ *
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef AES_WRAP_H
+#define AES_WRAP_H
+
+int __must_check aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
+int __must_check aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
+int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
+ const u8 *addr[], const size_t *len,
+ u8 *mac);
+int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len,
+ u8 *mac);
+int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
+int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
+ u8 *data, size_t data_len);
+int __must_check aes_128_eax_encrypt(const u8 *key,
+ const u8 *nonce, size_t nonce_len,
+ const u8 *hdr, size_t hdr_len,
+ u8 *data, size_t data_len, u8 *tag);
+int __must_check aes_128_eax_decrypt(const u8 *key,
+ const u8 *nonce, size_t nonce_len,
+ const u8 *hdr, size_t hdr_len,
+ u8 *data, size_t data_len, const u8 *tag);
+int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
+ size_t data_len);
+int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
+ size_t data_len);
+
+#endif /* AES_WRAP_H */
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/common.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/common.h
new file mode 100644
index 0000000..aaf82b9
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/common.h
@@ -0,0 +1,20 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MSG_DEBUG
+#define wpa_hexdump(x, args...)
+#define wpa_hexdump_key(x, args...)
+#define wpa_printf(x, args...)
+
+#define os_memcpy(x, y, z) memcpy(x, y, z)
+#define os_memcmp(x, y, z) memcmp(x, y, z)
+#define os_memset(x, y, z) memset(x, y, z)
+#define os_malloc(x) malloc(x)
+#define os_free(x) free(x)
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+
+#define __must_check
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/crypto.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/crypto.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/crypto.h
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/includes.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/includes.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/includes.h
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.c b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.c
new file mode 100644
index 0000000..cc4e95c
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.c
@@ -0,0 +1,329 @@
+/*
+ * 3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
+ * Copyright (c) 2006-2007 <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ *
+ * This file implements an example authentication algorithm defined for 3GPP
+ * AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow
+ * EAP-AKA to be tested properly with real USIM cards.
+ *
+ * This implementations assumes that the r1..r5 and c1..c5 constants defined in
+ * TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00,
+ * c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to
+ * be AES (Rijndael).
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "aes_wrap.h"
+#include "milenage.h"
+
+
+/**
+ * milenage_f1 - Milenage f1 and f1* algorithms
+ * @opc: OPc = 128-bit value derived from OP and K
+ * @k: K = 128-bit subscriber key
+ * @_rand: RAND = 128-bit random challenge
+ * @sqn: SQN = 48-bit sequence number
+ * @amf: AMF = 16-bit authentication management field
+ * @mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL
+ * @mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
+ * Returns: 0 on success, -1 on failure
+ */
+int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
+ const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s)
+{
+ u8 tmp1[16], tmp2[16], tmp3[16];
+ int i;
+
+ /* tmp1 = TEMP = E_K(RAND XOR OP_C) */
+ for (i = 0; i < 16; i++)
+ tmp1[i] = _rand[i] ^ opc[i];
+ if (aes_128_encrypt_block(k, tmp1, tmp1))
+ return -1;
+
+ /* tmp2 = IN1 = SQN || AMF || SQN || AMF */
+ os_memcpy(tmp2, sqn, 6);
+ os_memcpy(tmp2 + 6, amf, 2);
+ os_memcpy(tmp2 + 8, tmp2, 8);
+
+ /* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */
+
+ /* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */
+ for (i = 0; i < 16; i++)
+ tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i];
+ /* XOR with TEMP = E_K(RAND XOR OP_C) */
+ for (i = 0; i < 16; i++)
+ tmp3[i] ^= tmp1[i];
+ /* XOR with c1 (= ..00, i.e., NOP) */
+
+ /* f1 || f1* = E_K(tmp3) XOR OP_c */
+ if (aes_128_encrypt_block(k, tmp3, tmp1))
+ return -1;
+ for (i = 0; i < 16; i++)
+ tmp1[i] ^= opc[i];
+ if (mac_a)
+ os_memcpy(mac_a, tmp1, 8); /* f1 */
+ if (mac_s)
+ os_memcpy(mac_s, tmp1 + 8, 8); /* f1* */
+ return 0;
+}
+
+
+/**
+ * milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms
+ * @opc: OPc = 128-bit value derived from OP and K
+ * @k: K = 128-bit subscriber key
+ * @_rand: RAND = 128-bit random challenge
+ * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
+ * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
+ * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
+ * @ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL
+ * @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL
+ * Returns: 0 on success, -1 on failure
+ */
+int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
+ u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar)
+{
+ u8 tmp1[16], tmp2[16], tmp3[16];
+ int i;
+
+ /* tmp2 = TEMP = E_K(RAND XOR OP_C) */
+ for (i = 0; i < 16; i++)
+ tmp1[i] = _rand[i] ^ opc[i];
+ if (aes_128_encrypt_block(k, tmp1, tmp2))
+ return -1;
+
+ /* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */
+ /* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */
+ /* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */
+ /* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */
+
+ /* f2 and f5 */
+ /* rotate by r2 (= 0, i.e., NOP) */
+ for (i = 0; i < 16; i++)
+ tmp1[i] = tmp2[i] ^ opc[i];
+ tmp1[15] ^= 1; /* XOR c2 (= ..01) */
+ /* f5 || f2 = E_K(tmp1) XOR OP_c */
+ if (aes_128_encrypt_block(k, tmp1, tmp3))
+ return -1;
+ for (i = 0; i < 16; i++)
+ tmp3[i] ^= opc[i];
+ if (res)
+ os_memcpy(res, tmp3 + 8, 8); /* f2 */
+ if (ak)
+ os_memcpy(ak, tmp3, 6); /* f5 */
+
+ /* f3 */
+ if (ck) {
+ /* rotate by r3 = 0x20 = 4 bytes */
+ for (i = 0; i < 16; i++)
+ tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i];
+ tmp1[15] ^= 2; /* XOR c3 (= ..02) */
+ if (aes_128_encrypt_block(k, tmp1, ck))
+ return -1;
+ for (i = 0; i < 16; i++)
+ ck[i] ^= opc[i];
+ }
+
+ /* f4 */
+ if (ik) {
+ /* rotate by r4 = 0x40 = 8 bytes */
+ for (i = 0; i < 16; i++)
+ tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i];
+ tmp1[15] ^= 4; /* XOR c4 (= ..04) */
+ if (aes_128_encrypt_block(k, tmp1, ik))
+ return -1;
+ for (i = 0; i < 16; i++)
+ ik[i] ^= opc[i];
+ }
+
+ /* f5* */
+ if (akstar) {
+ /* rotate by r5 = 0x60 = 12 bytes */
+ for (i = 0; i < 16; i++)
+ tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i];
+ tmp1[15] ^= 8; /* XOR c5 (= ..08) */
+ if (aes_128_encrypt_block(k, tmp1, tmp1))
+ return -1;
+ for (i = 0; i < 6; i++)
+ akstar[i] = tmp1[i] ^ opc[i];
+ }
+
+ return 0;
+}
+
+
+/**
+ * milenage_generate - Generate AKA AUTN,IK,CK,RES
+ * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
+ * @amf: AMF = 16-bit authentication management field
+ * @k: K = 128-bit subscriber key
+ * @sqn: SQN = 48-bit sequence number
+ * @_rand: RAND = 128-bit random challenge
+ * @autn: Buffer for AUTN = 128-bit authentication token
+ * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
+ * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
+ * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
+ * @res_len: Max length for res; set to used length or 0 on failure
+ */
+void milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
+ const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
+ u8 *ck, u8 *res, size_t *res_len)
+{
+ int i;
+ u8 mac_a[8], ak[6];
+
+ if (*res_len < 8) {
+ *res_len = 0;
+ return;
+ }
+ if (milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) ||
+ milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) {
+ *res_len = 0;
+ return;
+ }
+ *res_len = 8;
+
+ /* AUTN = (SQN ^ AK) || AMF || MAC */
+ for (i = 0; i < 6; i++)
+ autn[i] = sqn[i] ^ ak[i];
+ os_memcpy(autn + 6, amf, 2);
+ os_memcpy(autn + 8, mac_a, 8);
+}
+
+
+/**
+ * milenage_auts - Milenage AUTS validation
+ * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
+ * @k: K = 128-bit subscriber key
+ * @_rand: RAND = 128-bit random challenge
+ * @auts: AUTS = 112-bit authentication token from client
+ * @sqn: Buffer for SQN = 48-bit sequence number
+ * Returns: 0 = success (sqn filled), -1 on failure
+ */
+int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
+ u8 *sqn)
+{
+ u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
+ u8 ak[6], mac_s[8];
+ int i;
+
+ if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
+ return -1;
+ for (i = 0; i < 6; i++)
+ sqn[i] = auts[i] ^ ak[i];
+ if (milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) ||
+ memcmp(mac_s, auts + 6, 8) != 0)
+ return -1;
+ return 0;
+}
+
+
+/**
+ * gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet
+ * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
+ * @k: K = 128-bit subscriber key
+ * @_rand: RAND = 128-bit random challenge
+ * @sres: Buffer for SRES = 32-bit SRES
+ * @kc: Buffer for Kc = 64-bit Kc
+ * Returns: 0 on success, -1 on failure
+ */
+int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc)
+{
+ u8 res[8], ck[16], ik[16];
+ int i;
+
+ if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL))
+ return -1;
+
+ for (i = 0; i < 8; i++)
+ kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8];
+
+#ifdef GSM_MILENAGE_ALT_SRES
+ os_memcpy(sres, res, 4);
+#else /* GSM_MILENAGE_ALT_SRES */
+ for (i = 0; i < 4; i++)
+ sres[i] = res[i] ^ res[i + 4];
+#endif /* GSM_MILENAGE_ALT_SRES */
+ return 0;
+}
+
+
+/**
+ * milenage_generate - Generate AKA AUTN,IK,CK,RES
+ * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
+ * @k: K = 128-bit subscriber key
+ * @sqn: SQN = 48-bit sequence number
+ * @_rand: RAND = 128-bit random challenge
+ * @autn: AUTN = 128-bit authentication token
+ * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
+ * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
+ * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
+ * @res_len: Variable that will be set to RES length
+ * @auts: 112-bit buffer for AUTS
+ * Returns: 0 on success, -1 on failure, or -2 on synchronization failure
+ */
+int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
+ const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
+ u8 *auts)
+{
+ int i;
+ u8 mac_a[8], ak[6], rx_sqn[6];
+ const u8 *amf;
+
+ wpa_hexdump(MSG_DEBUG, "Milenage: AUTN", autn, 16);
+ wpa_hexdump(MSG_DEBUG, "Milenage: RAND", _rand, 16);
+
+ if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
+ return -1;
+
+ *res_len = 8;
+ wpa_hexdump_key(MSG_DEBUG, "Milenage: RES", res, *res_len);
+ wpa_hexdump_key(MSG_DEBUG, "Milenage: CK", ck, 16);
+ wpa_hexdump_key(MSG_DEBUG, "Milenage: IK", ik, 16);
+ wpa_hexdump_key(MSG_DEBUG, "Milenage: AK", ak, 6);
+
+ /* AUTN = (SQN ^ AK) || AMF || MAC */
+ for (i = 0; i < 6; i++)
+ rx_sqn[i] = autn[i] ^ ak[i];
+ wpa_hexdump(MSG_DEBUG, "Milenage: SQN", rx_sqn, 6);
+
+ if (os_memcmp(rx_sqn, sqn, 6) <= 0) {
+ u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
+ if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
+ return -1;
+ wpa_hexdump_key(MSG_DEBUG, "Milenage: AK*", ak, 6);
+ for (i = 0; i < 6; i++)
+ auts[i] = sqn[i] ^ ak[i];
+ if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6))
+ return -1;
+ wpa_hexdump(MSG_DEBUG, "Milenage: AUTS", auts, 14);
+ return -2;
+ }
+
+ amf = autn + 6;
+ wpa_hexdump(MSG_DEBUG, "Milenage: AMF", amf, 2);
+ if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL))
+ return -1;
+
+ wpa_hexdump(MSG_DEBUG, "Milenage: MAC_A", mac_a, 8);
+
+ if (os_memcmp(mac_a, autn + 8, 8) != 0) {
+ wpa_printf(MSG_DEBUG, "Milenage: MAC mismatch");
+ wpa_hexdump(MSG_DEBUG, "Milenage: Received MAC_A",
+ autn + 8, 8);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.h b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.h
new file mode 100644
index 0000000..d5054d6
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/gsm/milenage/milenage.h
@@ -0,0 +1,33 @@
+/*
+ * UMTS AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
+ * Copyright (c) 2006-2007 <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef MILENAGE_H
+#define MILENAGE_H
+
+void milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
+ const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
+ u8 *ck, u8 *res, size_t *res_len);
+int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
+ u8 *sqn);
+int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres,
+ u8 *kc);
+int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
+ const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
+ u8 *auts);
+int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
+ const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s);
+int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
+ u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar);
+
+#endif /* MILENAGE_H */
diff --git a/Src/osmolib/src/shared/libosmocore/src/gsmtap_util.c b/Src/osmolib/src/shared/libosmocore/src/gsmtap_util.c
index 0e4d61e..ce722da 100644
--- a/Src/osmolib/src/shared/libosmocore/src/gsmtap_util.c
+++ b/Src/osmolib/src/shared/libosmocore/src/gsmtap_util.c
@@ -88,7 +88,8 @@ uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id)
return ret;
}
-/*! \brief create L1/L2 data and put it into GSMTAP
+/*! \brief create an arbitrary type GSMTAP message
+ * \param[in] type The GSMTAP_TYPE_xxx constant of the message to create
* \param[in] arfcn GSM ARFCN (Channel Number)
* \param[in] ts GSM time slot
* \param[in] chan_type Channel Type
@@ -102,7 +103,7 @@ uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id)
* This function will allocate a new msgb and fill it with a GSMTAP
* header containing the information
*/
-struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
+struct msgb *gsmtap_makemsg_ex(uint8_t type, uint16_t arfcn, uint8_t ts, uint8_t chan_type,
uint8_t ss, uint32_t fn, int8_t signal_dbm,
uint8_t snr, const uint8_t *data, unsigned int len)
{
@@ -118,7 +119,7 @@ struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
gh->version = GSMTAP_VERSION;
gh->hdr_len = sizeof(*gh)/4;
- gh->type = GSMTAP_TYPE_UM;
+ gh->type = type;
gh->timeslot = ts;
gh->sub_slot = ss;
gh->arfcn = htons(arfcn);
@@ -134,6 +135,28 @@ struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
return msg;
}
+/*! \brief create L1/L2 data and put it into GSMTAP
+ * \param[in] arfcn GSM ARFCN (Channel Number)
+ * \param[in] ts GSM time slot
+ * \param[in] chan_type Channel Type
+ * \param[in] ss Sub-slot
+ * \param[in] fn GSM Frame Number
+ * \param[in] signal_dbm Signal Strength (dBm)
+ * \param[in] snr Signal/Noise Ratio (SNR)
+ * \param[in] data Pointer to data buffer
+ * \param[in] len Length of \ref data
+ *
+ * This function will allocate a new msgb and fill it with a GSMTAP
+ * header containing the information
+ */
+struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
+ uint8_t ss, uint32_t fn, int8_t signal_dbm,
+ uint8_t snr, const uint8_t *data, unsigned int len)
+{
+ return gsmtap_makemsg_ex(GSMTAP_TYPE_UM, arfcn, ts, chan_type,
+ ss, fn, signal_dbm, snr, data, len);
+}
+
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -208,8 +231,10 @@ int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg)
}
}
-/*! \brief receive a message from L1/L2 and put it in GSMTAP */
-int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
+/*! \brief send an arbitrary type through GSMTAP.
+ * See \ref gsmtap_makemsg_ex for arguments
+ */
+int gsmtap_send_ex(struct gsmtap_inst *gti, uint8_t type, uint16_t arfcn, uint8_t ts,
uint8_t chan_type, uint8_t ss, uint32_t fn,
int8_t signal_dbm, uint8_t snr, const uint8_t *data,
unsigned int len)
@@ -219,7 +244,7 @@ int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
if (!gti)
return -ENODEV;
- msg = gsmtap_makemsg(arfcn, ts, chan_type, ss, fn, signal_dbm,
+ msg = gsmtap_makemsg_ex(type, arfcn, ts, chan_type, ss, fn, signal_dbm,
snr, data, len);
if (!msg)
return -ENOMEM;
@@ -227,6 +252,18 @@ int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
return gsmtap_sendmsg(gti, msg);
}
+/*! \brief send a message from L1/L2 through GSMTAP.
+ * See \ref gsmtap_makemsg for arguments
+ */
+int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
+ uint8_t chan_type, uint8_t ss, uint32_t fn,
+ int8_t signal_dbm, uint8_t snr, const uint8_t *data,
+ unsigned int len)
+{
+ return gsmtap_send_ex(gti, GSMTAP_TYPE_UM, arfcn, ts, chan_type, ss, fn,
+ signal_dbm, snr, data, len);
+}
+
/* Callback from select layer if we can write to the socket */
static int gsmtap_wq_w_cb(struct osmo_fd *ofd, struct msgb *msg)
{
diff --git a/Src/osmolib/src/shared/libosmocore/src/logging.c b/Src/osmolib/src/shared/libosmocore/src/logging.c
index 9dd63e7..f8ed4cb 100644
--- a/Src/osmolib/src/shared/libosmocore/src/logging.c
+++ b/Src/osmolib/src/shared/libosmocore/src/logging.c
@@ -72,9 +72,9 @@ static const struct log_info_cat internal_cat[OSMO_NUM_DLIB] = {
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
- [INT2IDX(DLLAPDM)] = { /* -2 becomes 1 */
- .name = "DLLAPDM",
- .description = "LAPDm in libosmogsm",
+ [INT2IDX(DLLAPD)] = { /* -2 becomes 1 */
+ .name = "DLLAPD",
+ .description = "LAPD in libosmogsm",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
@@ -100,6 +100,12 @@ static const struct log_info_cat internal_cat[OSMO_NUM_DLIB] = {
.description = "A-bis Input Driver for B-Channels (voice)",
.enabled = 0, .loglevel = LOGL_NOTICE,
},
+ [INT2IDX(DLSMS)] = {
+ .name = "DLSMS",
+ .description = "Layer3 Short Message Service (SMS)",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ .color = "\033[1;38m",
+ },
};
/* You have to keep this in sync with the structure loglevel_strs. */
diff --git a/Src/osmolib/src/shared/libosmocore/src/logging_syslog.c b/Src/osmolib/src/shared/libosmocore/src/logging_syslog.c
index b07b7fe..119dd74 100644
--- a/Src/osmolib/src/shared/libosmocore/src/logging_syslog.c
+++ b/Src/osmolib/src/shared/libosmocore/src/logging_syslog.c
@@ -43,7 +43,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
-static const int logp2syslog_level(unsigned int level)
+static int logp2syslog_level(unsigned int level)
{
if (level >= LOGL_FATAL)
return LOG_CRIT;
diff --git a/Src/osmolib/src/shared/libosmocore/src/rbtree.c b/Src/osmolib/src/shared/libosmocore/src/rbtree.c
new file mode 100644
index 0000000..4e7c0f3
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/src/rbtree.c
@@ -0,0 +1,383 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+ (C) 2002 David Woodhouse <dwmw2@infradead.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ linux/lib/rbtree.c
+*/
+
+#include <osmocom/core/linuxrbtree.h>
+
+static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *right = node->rb_right;
+ struct rb_node *parent = rb_parent(node);
+
+ if ((node->rb_right = right->rb_left))
+ rb_set_parent(right->rb_left, node);
+ right->rb_left = node;
+
+ rb_set_parent(right, parent);
+
+ if (parent)
+ {
+ if (node == parent->rb_left)
+ parent->rb_left = right;
+ else
+ parent->rb_right = right;
+ }
+ else
+ root->rb_node = right;
+ rb_set_parent(node, right);
+}
+
+static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *left = node->rb_left;
+ struct rb_node *parent = rb_parent(node);
+
+ if ((node->rb_left = left->rb_right))
+ rb_set_parent(left->rb_right, node);
+ left->rb_right = node;
+
+ rb_set_parent(left, parent);
+
+ if (parent)
+ {
+ if (node == parent->rb_right)
+ parent->rb_right = left;
+ else
+ parent->rb_left = left;
+ }
+ else
+ root->rb_node = left;
+ rb_set_parent(node, left);
+}
+
+void rb_insert_color(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *parent, *gparent;
+
+ while ((parent = rb_parent(node)) && rb_is_red(parent))
+ {
+ gparent = rb_parent(parent);
+
+ if (parent == gparent->rb_left)
+ {
+ {
+ register struct rb_node *uncle = gparent->rb_right;
+ if (uncle && rb_is_red(uncle))
+ {
+ rb_set_black(uncle);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ node = gparent;
+ continue;
+ }
+ }
+
+ if (parent->rb_right == node)
+ {
+ register struct rb_node *tmp;
+ __rb_rotate_left(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ __rb_rotate_right(gparent, root);
+ } else {
+ {
+ register struct rb_node *uncle = gparent->rb_left;
+ if (uncle && rb_is_red(uncle))
+ {
+ rb_set_black(uncle);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ node = gparent;
+ continue;
+ }
+ }
+
+ if (parent->rb_left == node)
+ {
+ register struct rb_node *tmp;
+ __rb_rotate_right(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ __rb_rotate_left(gparent, root);
+ }
+ }
+
+ rb_set_black(root->rb_node);
+}
+
+static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
+ struct rb_root *root)
+{
+ struct rb_node *other;
+
+ while ((!node || rb_is_black(node)) && node != root->rb_node)
+ {
+ if (parent->rb_left == node)
+ {
+ other = parent->rb_right;
+ if (rb_is_red(other))
+ {
+ rb_set_black(other);
+ rb_set_red(parent);
+ __rb_rotate_left(parent, root);
+ other = parent->rb_right;
+ }
+ if ((!other->rb_left || rb_is_black(other->rb_left)) &&
+ (!other->rb_right || rb_is_black(other->rb_right)))
+ {
+ rb_set_red(other);
+ node = parent;
+ parent = rb_parent(node);
+ }
+ else
+ {
+ if (!other->rb_right || rb_is_black(other->rb_right))
+ {
+ rb_set_black(other->rb_left);
+ rb_set_red(other);
+ __rb_rotate_right(other, root);
+ other = parent->rb_right;
+ }
+ rb_set_color(other, rb_color(parent));
+ rb_set_black(parent);
+ rb_set_black(other->rb_right);
+ __rb_rotate_left(parent, root);
+ node = root->rb_node;
+ break;
+ }
+ }
+ else
+ {
+ other = parent->rb_left;
+ if (rb_is_red(other))
+ {
+ rb_set_black(other);
+ rb_set_red(parent);
+ __rb_rotate_right(parent, root);
+ other = parent->rb_left;
+ }
+ if ((!other->rb_left || rb_is_black(other->rb_left)) &&
+ (!other->rb_right || rb_is_black(other->rb_right)))
+ {
+ rb_set_red(other);
+ node = parent;
+ parent = rb_parent(node);
+ }
+ else
+ {
+ if (!other->rb_left || rb_is_black(other->rb_left))
+ {
+ rb_set_black(other->rb_right);
+ rb_set_red(other);
+ __rb_rotate_left(other, root);
+ other = parent->rb_left;
+ }
+ rb_set_color(other, rb_color(parent));
+ rb_set_black(parent);
+ rb_set_black(other->rb_left);
+ __rb_rotate_right(parent, root);
+ node = root->rb_node;
+ break;
+ }
+ }
+ }
+ if (node)
+ rb_set_black(node);
+}
+
+void rb_erase(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *child, *parent;
+ int color;
+
+ if (!node->rb_left)
+ child = node->rb_right;
+ else if (!node->rb_right)
+ child = node->rb_left;
+ else
+ {
+ struct rb_node *old = node, *left;
+
+ node = node->rb_right;
+ while ((left = node->rb_left) != NULL)
+ node = left;
+
+ if (rb_parent(old)) {
+ if (rb_parent(old)->rb_left == old)
+ rb_parent(old)->rb_left = node;
+ else
+ rb_parent(old)->rb_right = node;
+ } else
+ root->rb_node = node;
+
+ child = node->rb_right;
+ parent = rb_parent(node);
+ color = rb_color(node);
+
+ if (parent == old) {
+ parent = node;
+ } else {
+ if (child)
+ rb_set_parent(child, parent);
+ parent->rb_left = child;
+
+ node->rb_right = old->rb_right;
+ rb_set_parent(old->rb_right, node);
+ }
+
+ node->rb_parent_color = old->rb_parent_color;
+ node->rb_left = old->rb_left;
+ rb_set_parent(old->rb_left, node);
+
+ goto color;
+ }
+
+ parent = rb_parent(node);
+ color = rb_color(node);
+
+ if (child)
+ rb_set_parent(child, parent);
+ if (parent)
+ {
+ if (parent->rb_left == node)
+ parent->rb_left = child;
+ else
+ parent->rb_right = child;
+ }
+ else
+ root->rb_node = child;
+
+ color:
+ if (color == RB_BLACK)
+ __rb_erase_color(child, parent, root);
+}
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+struct rb_node *rb_first(const struct rb_root *root)
+{
+ struct rb_node *n;
+
+ n = root->rb_node;
+ if (!n)
+ return NULL;
+ while (n->rb_left)
+ n = n->rb_left;
+ return n;
+}
+
+struct rb_node *rb_last(const struct rb_root *root)
+{
+ struct rb_node *n;
+
+ n = root->rb_node;
+ if (!n)
+ return NULL;
+ while (n->rb_right)
+ n = n->rb_right;
+ return n;
+}
+
+struct rb_node *rb_next(const struct rb_node *node)
+{
+ struct rb_node *parent;
+
+ if (rb_parent(node) == node)
+ return NULL;
+
+ /* If we have a right-hand child, go down and then left as far
+ as we can. */
+ if (node->rb_right) {
+ node = node->rb_right;
+ while (node->rb_left)
+ node=node->rb_left;
+ return (struct rb_node *)node;
+ }
+
+ /* No right-hand children. Everything down and left is
+ smaller than us, so any 'next' node must be in the general
+ direction of our parent. Go up the tree; any time the
+ ancestor is a right-hand child of its parent, keep going
+ up. First time it's a left-hand child of its parent, said
+ parent is our 'next' node. */
+ while ((parent = rb_parent(node)) && node == parent->rb_right)
+ node = parent;
+
+ return parent;
+}
+
+struct rb_node *rb_prev(const struct rb_node *node)
+{
+ struct rb_node *parent;
+
+ if (rb_parent(node) == node)
+ return NULL;
+
+ /* If we have a left-hand child, go down and then right as far
+ as we can. */
+ if (node->rb_left) {
+ node = node->rb_left;
+ while (node->rb_right)
+ node=node->rb_right;
+ return (struct rb_node *)node;
+ }
+
+ /* No left-hand children. Go up till we find an ancestor which
+ is a right-hand child of its parent */
+ while ((parent = rb_parent(node)) && node == parent->rb_left)
+ node = parent;
+
+ return parent;
+}
+
+void rb_replace_node(struct rb_node *victim, struct rb_node *new,
+ struct rb_root *root)
+{
+ struct rb_node *parent = rb_parent(victim);
+
+ /* Set the surrounding nodes to point to the replacement */
+ if (parent) {
+ if (victim == parent->rb_left)
+ parent->rb_left = new;
+ else
+ parent->rb_right = new;
+ } else {
+ root->rb_node = new;
+ }
+ if (victim->rb_left)
+ rb_set_parent(victim->rb_left, new);
+ if (victim->rb_right)
+ rb_set_parent(victim->rb_right, new);
+
+ /* Copy the pointers/colour from the victim to the replacement */
+ *new = *victim;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/src/serial.c b/Src/osmolib/src/shared/libosmocore/src/serial.c
index 26cf59d..bc64b8a 100644
--- a/Src/osmolib/src/shared/libosmocore/src/serial.c
+++ b/Src/osmolib/src/shared/libosmocore/src/serial.c
@@ -38,8 +38,9 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef __linux__
#include <linux/serial.h>
-
+#endif
#include <osmocom/core/serial.h>
@@ -155,6 +156,7 @@ osmo_serial_set_baudrate(int fd, speed_t baudrate)
int
osmo_serial_set_custom_baudrate(int fd, int baudrate)
{
+#ifdef __linux__
int rc;
struct serial_struct ser_info;
@@ -174,6 +176,23 @@ osmo_serial_set_custom_baudrate(int fd, int baudrate)
}
return _osmo_serial_set_baudrate(fd, B38400); /* 38400 is a kind of magic ... */
+#elif defined(__APPLE__)
+#ifndef IOSSIOSPEED
+#define IOSSIOSPEED _IOW('T', 2, speed_t)
+#endif
+ int rc;
+
+ unsigned int speed = baudrate;
+ rc = ioctl(fd, IOSSIOSPEED, &speed);
+ if (rc < 0) {
+ dbg_perror("ioctl(IOSSIOSPEED)");
+ return -errno;
+ }
+ return 0;
+#else
+#warning osmo_serial_set_custom_baudrate: unsupported platform
+ return 0;
+#endif
}
/*! \brief Clear any custom baudrate
@@ -185,6 +204,7 @@ osmo_serial_set_custom_baudrate(int fd, int baudrate)
int
osmo_serial_clear_custom_baudrate(int fd)
{
+#ifdef __linux__
int rc;
struct serial_struct ser_info;
@@ -202,7 +222,7 @@ osmo_serial_clear_custom_baudrate(int fd)
dbg_perror("ioctl(TIOCSSERIAL)");
return -errno;
}
-
+#endif
return 0;
}
diff --git a/Src/osmolib/src/shared/libosmocore/src/socket.c b/Src/osmolib/src/shared/libosmocore/src/socket.c
index 1a1d71d..8a8829b 100644
--- a/Src/osmolib/src/shared/libosmocore/src/socket.c
+++ b/Src/osmolib/src/shared/libosmocore/src/socket.c
@@ -18,6 +18,8 @@
#include <sys/socket.h>
#include <sys/types.h>
+#include <netinet/in.h>
+
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
diff --git a/Src/osmolib/src/shared/libosmocore/src/timer.c b/Src/osmolib/src/shared/libosmocore/src/timer.c
index ed2b296..79d4ad6 100644
--- a/Src/osmolib/src/shared/libosmocore/src/timer.c
+++ b/Src/osmolib/src/shared/libosmocore/src/timer.c
@@ -1,7 +1,12 @@
/*
* (C) 2008,2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2011 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
+ * Authors: Holger Hans Peter Freyther <zecke@selfish.org>
+ * Harald Welte <laforge@gnumonks.org>
+ * Pablo Neira Ayuso <pablo@gnumonks.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -18,6 +23,10 @@
*
*/
+/* These store the amount of time that we wait until next timer expires. */
+static struct timeval nearest;
+static struct timeval *nearest_p;
+
/*! \addtogroup timer
* @{
*/
@@ -27,35 +36,43 @@
#include <assert.h>
#include <string.h>
+#include <limits.h>
#include <osmocom/core/timer.h>
+#include <osmocom/core/timer_compat.h>
+#include <osmocom/core/linuxlist.h>
+
+static struct rb_root timer_root = RB_ROOT;
+
+static void __add_timer(struct osmo_timer_list *timer)
+{
+ struct rb_node **new = &(timer_root.rb_node);
+ struct rb_node *parent = NULL;
-static LLIST_HEAD(timer_list);
-static struct timeval s_nearest_time;
-static struct timeval s_select_time;
+ while (*new) {
+ struct osmo_timer_list *this;
-#define MICRO_SECONDS 1000000LL
+ this = container_of(*new, struct osmo_timer_list, node);
-#define TIME_SMALLER(left, right) \
- (left.tv_sec*MICRO_SECONDS+left.tv_usec) <= (right.tv_sec*MICRO_SECONDS+right.tv_usec)
+ parent = *new;
+ if (timercmp(&timer->timeout, &this->timeout, <))
+ new = &((*new)->rb_left);
+ else
+ new = &((*new)->rb_right);
+ }
+ rb_link_node(&timer->node, parent, new);
+ rb_insert_color(&timer->node, &timer_root);
+}
/*! \brief add a new timer to the timer management
* \param[in] timer the timer that should be added
*/
void osmo_timer_add(struct osmo_timer_list *timer)
{
- struct osmo_timer_list *list_timer;
-
- /* TODO: Optimize and remember the closest item... */
+ osmo_timer_del(timer);
timer->active = 1;
-
- /* this might be called from within update_timers */
- llist_for_each_entry(list_timer, &timer_list, entry)
- if (timer == list_timer)
- return;
-
- timer->in_list = 1;
- llist_add(&timer->entry, &timer_list);
+ INIT_LLIST_HEAD(&timer->list);
+ __add_timer(timer);
}
/*! \brief schedule a timer at a given future relative time
@@ -74,10 +91,9 @@ osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds
struct timeval current_time;
gettimeofday(&current_time, NULL);
- unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
- currentTime += seconds * MICRO_SECONDS + microseconds;
- timer->timeout.tv_sec = currentTime / MICRO_SECONDS;
- timer->timeout.tv_usec = currentTime % MICRO_SECONDS;
+ timer->timeout.tv_sec = seconds;
+ timer->timeout.tv_usec = microseconds;
+ timeradd(&timer->timeout, &current_time, &timer->timeout);
osmo_timer_add(timer);
}
@@ -89,10 +105,12 @@ osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds
*/
void osmo_timer_del(struct osmo_timer_list *timer)
{
- if (timer->in_list) {
+ if (timer->active) {
timer->active = 0;
- timer->in_list = 0;
- llist_del(&timer->entry);
+ rb_erase(&timer->node, &timer_root);
+ /* make sure this is not already scheduled for removal. */
+ if (!llist_empty(&timer->list))
+ llist_del_init(&timer->list);
}
}
@@ -116,26 +134,26 @@ int osmo_timer_pending(struct osmo_timer_list *timer)
*/
struct timeval *osmo_timers_nearest(void)
{
- struct timeval current_time;
-
- if (s_nearest_time.tv_sec == 0 && s_nearest_time.tv_usec == 0)
- return NULL;
-
- if (gettimeofday(&current_time, NULL) == -1)
- return NULL;
-
- unsigned long long nearestTime = s_nearest_time.tv_sec * MICRO_SECONDS + s_nearest_time.tv_usec;
- unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
+ /* nearest_p is exactly what we need already: NULL if nothing is
+ * waiting, {0,0} if we must dispatch immediately, and the correct
+ * delay if we need to wait */
+ return nearest_p;
+}
- if (nearestTime < currentTime) {
- s_select_time.tv_sec = 0;
- s_select_time.tv_usec = 0;
+static void update_nearest(struct timeval *cand, struct timeval *current)
+{
+ if (cand->tv_sec != LONG_MAX) {
+ if (timercmp(cand, current, >))
+ timersub(cand, current, &nearest);
+ else {
+ /* loop again inmediately */
+ nearest.tv_sec = 0;
+ nearest.tv_usec = 0;
+ }
+ nearest_p = &nearest;
} else {
- s_select_time.tv_sec = (nearestTime - currentTime) / MICRO_SECONDS;
- s_select_time.tv_usec = (nearestTime - currentTime) % MICRO_SECONDS;
+ nearest_p = NULL;
}
-
- return &s_select_time;
}
/*
@@ -143,17 +161,18 @@ struct timeval *osmo_timers_nearest(void)
*/
void osmo_timers_prepare(void)
{
- struct osmo_timer_list *timer, *nearest_timer = NULL;
- llist_for_each_entry(timer, &timer_list, entry) {
- if (!nearest_timer || TIME_SMALLER(timer->timeout, nearest_timer->timeout)) {
- nearest_timer = timer;
- }
- }
+ struct rb_node *node;
+ struct timeval current;
+
+ gettimeofday(&current, NULL);
- if (nearest_timer) {
- s_nearest_time = nearest_timer->timeout;
+ node = rb_first(&timer_root);
+ if (node) {
+ struct osmo_timer_list *this;
+ this = container_of(node, struct osmo_timer_list, node);
+ update_nearest(&this->timeout, &current);
} else {
- memset(&s_nearest_time, 0, sizeof(struct timeval));
+ nearest_p = NULL;
}
}
@@ -163,46 +182,41 @@ void osmo_timers_prepare(void)
int osmo_timers_update(void)
{
struct timeval current_time;
- struct osmo_timer_list *timer, *tmp;
+ struct rb_node *node;
+ struct llist_head timer_eviction_list;
+ struct osmo_timer_list *this;
int work = 0;
gettimeofday(&current_time, NULL);
+ INIT_LLIST_HEAD(&timer_eviction_list);
+ for (node = rb_first(&timer_root); node; node = rb_next(node)) {
+ this = container_of(node, struct osmo_timer_list, node);
+
+ if (timercmp(&this->timeout, &current_time, >))
+ break;
+
+ llist_add(&this->list, &timer_eviction_list);
+ }
+
/*
* The callbacks might mess with our list and in this case
* even llist_for_each_entry_safe is not safe to use. To allow
- * del_timer, add_timer, schedule_timer to be called from within
- * the callback we jump through some loops.
+ * osmo_timer_del to be called from within the callback we need
+ * to restart the iteration for each element scheduled for removal.
*
- * First we set the handled flag of each active timer to zero,
- * then we iterate over the list and execute the callbacks. As the
- * list might have been changed (specially the next) from within
- * the callback we have to start over again. Once every callback
- * is dispatched we will remove the non-active from the list.
- *
- * TODO: If this is a performance issue we can poison a global
- * variable in add_timer and del_timer and only then restart.
+ * The problematic scenario is the following: Given two timers A
+ * and B that have expired at the same time. Thus, they are both
+ * in the eviction list in this order: A, then B. If we remove
+ * timer B from the A's callback, we continue with B in the next
+ * iteration step, leading to an access-after-release.
*/
- llist_for_each_entry(timer, &timer_list, entry) {
- timer->handled = 0;
- }
-
restart:
- llist_for_each_entry(timer, &timer_list, entry) {
- if (!timer->handled && TIME_SMALLER(timer->timeout, current_time)) {
- timer->handled = 1;
- timer->active = 0;
- (*timer->cb)(timer->data);
- work = 1;
- goto restart;
- }
- }
-
- llist_for_each_entry_safe(timer, tmp, &timer_list, entry) {
- timer->handled = 0;
- if (!timer->active) {
- osmo_timer_del(timer);
- }
+ llist_for_each_entry(this, &timer_eviction_list, list) {
+ osmo_timer_del(this);
+ this->cb(this->data);
+ work = 1;
+ goto restart;
}
return work;
@@ -210,10 +224,10 @@ restart:
int osmo_timers_check(void)
{
- struct osmo_timer_list *timer;
+ struct rb_node *node;
int i = 0;
- llist_for_each_entry(timer, &timer_list, entry) {
+ for (node = rb_first(&timer_root); node; node = rb_next(node)) {
i++;
}
return i;
diff --git a/Src/osmolib/src/shared/libosmocore/src/utils.c b/Src/osmolib/src/shared/libosmocore/src/utils.c
index a25479f..0a970ac 100644
--- a/Src/osmolib/src/shared/libosmocore/src/utils.c
+++ b/Src/osmolib/src/shared/libosmocore/src/utils.c
@@ -173,11 +173,15 @@ char *osmo_hexdump(const unsigned char *buf, int len)
* This function will print a sequence of bytes as hexadecimal numbers,
* without any space character between each byte (e.g. "1aefd9")
*/
-char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
+char *osmo_hexdump_nospc(const unsigned char *buf, int len)
{
return _osmo_hexdump(buf, len, "");
}
+ /* Compat with previous typo to preserve abi */
+char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
+ __attribute__((weak, alias("osmo_hexdump_nospc")));
+
#include "../config.h"
#ifdef HAVE_CTYPE_H
#include <ctype.h>
diff --git a/Src/osmolib/src/shared/libosmocore/src/vty/logging_vty.c b/Src/osmolib/src/shared/libosmocore/src/vty/logging_vty.c
index b037a5b..6be30b4 100644
--- a/Src/osmolib/src/shared/libosmocore/src/vty/logging_vty.c
+++ b/Src/osmolib/src/shared/libosmocore/src/vty/logging_vty.c
@@ -185,9 +185,10 @@ DEFUN(logging_level,
DEFUN(logging_set_category_mask,
logging_set_category_mask_cmd,
- "logging set log mask MASK",
+ "logging set-log-mask MASK",
LOGGING_STR
- "Decide which categories to output.\n")
+ "Set the logmask of this logging target\n"
+ "The logmask to use\n")
{
struct log_target *tgt = osmo_log_vty2tgt(vty);
@@ -198,6 +199,14 @@ DEFUN(logging_set_category_mask,
return CMD_SUCCESS;
}
+ALIAS_DEPRECATED(logging_set_category_mask,
+ logging_set_category_mask_old_cmd,
+ "logging set log mask MASK",
+ LOGGING_STR
+ "Decide which categories to output.\n"
+ "Log commands\n" "Mask commands\n" "The logmask to use\n");
+
+
DEFUN(diable_logging,
disable_logging_cmd,
"logging disable",
@@ -381,7 +390,16 @@ static struct value_string sysl_level_names[] = {
DEFUN(cfg_log_syslog, cfg_log_syslog_cmd,
"log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)",
- LOG_STR "Logging via syslog\n")
+ LOG_STR "Logging via syslog\n"
+ "Security/authorization messages facility\n"
+ "Clock daemon (cron/at) facility\n"
+ "General system daemon facility\n"
+ "Ftp daemon facility\n"
+ "Line printer facility\n"
+ "Mail facility\n"
+ "News facility\n"
+ "Generic facility\n"
+ "UUCP facility\n")
{
int facility = get_string_value(sysl_level_names, argv[0]);
@@ -560,6 +578,7 @@ void logging_vty_add_cmds(const struct log_info *cat)
install_element_ve(&logging_use_clr_cmd);
install_element_ve(&logging_prnt_timestamp_cmd);
install_element_ve(&logging_set_category_mask_cmd);
+ install_element_ve(&logging_set_category_mask_old_cmd);
/* Logging level strings are generated dynamically. */
logging_level_cmd.string = log_vty_command_string(cat);
diff --git a/Src/osmolib/src/shared/libosmocore/src/vty/telnet_interface.c b/Src/osmolib/src/shared/libosmocore/src/vty/telnet_interface.c
index ed64cda..167acc1 100644
--- a/Src/osmolib/src/shared/libosmocore/src/vty/telnet_interface.c
+++ b/Src/osmolib/src/shared/libosmocore/src/vty/telnet_interface.c
@@ -221,4 +221,16 @@ void vty_event(enum event event, int sock, struct vty *vty)
}
}
+void telnet_exit(void)
+{
+ struct telnet_connection *tc, *tc2;
+
+ llist_for_each_entry_safe(tc, tc2, &active_connections, entry)
+ telnet_close_client(&tc->fd);
+
+ osmo_fd_unregister(&server_socket);
+ close(server_socket.fd);
+ talloc_free(tall_telnet_ctx);
+}
+
/*! }@ */
diff --git a/Src/osmolib/src/shared/libosmocore/src/vty/vty.c b/Src/osmolib/src/shared/libosmocore/src/vty/vty.c
index 5f5e6a4..da03596 100644
--- a/Src/osmolib/src/shared/libosmocore/src/vty/vty.c
+++ b/Src/osmolib/src/shared/libosmocore/src/vty/vty.c
@@ -802,9 +802,11 @@ static void vty_backward_word(struct vty *vty)
static void vty_down_level(struct vty *vty)
{
vty_out(vty, "%s", VTY_NEWLINE);
- /* FIXME: we need to call the exit function of the specific node
- * in question, not this generic one that doesn't know all nodes */
- (*config_exit_cmd.func) (NULL, vty, 0, NULL);
+ /* call the exit function of the specific node */
+ if (vty->node > CONFIG_NODE)
+ vty_go_parent(vty);
+ else
+ (*config_exit_cmd.func) (NULL, vty, 0, NULL);
vty_prompt(vty);
vty->cp = 0;
}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/Makefile.am
index 6c3cb33..eff1ac4 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/Makefile.am
@@ -1,6 +1,47 @@
if ENABLE_TESTS
-SUBDIRS = timer sms ussd smscb bits
+SUBDIRS = timer sms ussd smscb bits a5 conv auth lapd gsm0808
if ENABLE_MSGFILE
SUBDIRS += msgfile
endif
+
+
+# The `:;' works around a Bash 3.2 bug when the output is not writeable.
+$(srcdir)/package.m4: $(top_srcdir)/configure.ac
+ :;{ \
+ echo '# Signature of the current package.' && \
+ echo 'm4_define([AT_PACKAGE_NAME],' && \
+ echo ' [$(PACKAGE_NAME)])' && \
+ echo 'm4_define([AT_PACKAGE_TARNAME],' && \
+ echo ' [$(PACKAGE_TARNAME)])' && \
+ echo 'm4_define([AT_PACKAGE_VERSION],' && \
+ echo ' [$(PACKAGE_VERSION)])' && \
+ echo 'm4_define([AT_PACKAGE_STRING],' && \
+ echo ' [$(PACKAGE_STRING)])' && \
+ echo 'm4_define([AT_PACKAGE_BUGREPORT],' && \
+ echo ' [$(PACKAGE_BUGREPORT)])'; \
+ echo 'm4_define([AT_PACKAGE_URL],' && \
+ echo ' [$(PACKAGE_URL)])'; \
+ } >'$(srcdir)/package.m4'
+
+EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE)
+TESTSUITE = $(srcdir)/testsuite
+
+check-local: atconfig $(TESTSUITE)
+ $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS)
+
+installcheck-local: atconfig $(TESTSUITE)
+ $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' \
+ $(TESTSUITEFLAGS)
+
+clean-local:
+ test ! -f '$(TESTSUITE)' || \
+ $(SHELL) '$(TESTSUITE)' --clean
+ $(RM) -f atconfig
+
+AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te
+AUTOTEST = $(AUTOM4TE) --language=autotest
+$(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4
+ $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+ mv $@.tmp $@
+
endif
diff --git a/Src/osmolib/src/shared/libosmocore/tests/a5/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/a5/Makefile.am
new file mode 100644
index 0000000..3c6e6ba
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/a5/Makefile.am
@@ -0,0 +1,6 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+noinst_PROGRAMS = a5_test
+EXTRA_DIST = a5_test.ok
+
+a5_test_SOURCES = a5_test.c
+a5_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.c b/Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.c
new file mode 100644
index 0000000..14436f1
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.c
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/a5.h>
+
+static const uint8_t key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
+static const uint32_t fn = 123456;
+static const uint8_t dl[] = {
+ /* A5/0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* A5/1 */
+ 0xcb, 0xa2, 0x55, 0x76, 0x17, 0x5d, 0x3b, 0x1c,
+ 0x7b, 0x2f, 0x29, 0xa8, 0xc1, 0xb6, 0x00,
+
+ /* A5/2 */
+ 0x45, 0x9c, 0x88, 0xc3, 0x82, 0xb7, 0xff, 0xb3,
+ 0x98, 0xd2, 0xf9, 0x6e, 0x0f, 0x14, 0x80,
+};
+static const uint8_t ul[] = {
+ /* A5/0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* A5/1 */
+ 0xd9, 0x03, 0x5e, 0x0f, 0x2a, 0xec, 0x13, 0x9a,
+ 0x05, 0xd4, 0xa8, 0x7b, 0xb1, 0x64, 0x80,
+
+ /* A5/2 */
+ 0xf0, 0x3a, 0xac, 0xde, 0xe3, 0x5b, 0x5e, 0x65,
+ 0x80, 0xba, 0xab, 0xc0, 0x59, 0x26, 0x40,
+};
+
+static const char *
+binstr(ubit_t *d, int n)
+{
+ static char str[256];
+ int i;
+
+ for (i=0; i<n; i++)
+ str[i] = d[i] ? '1' : '0';
+
+ str[i] = '\0';
+
+ return str;
+}
+
+int main(int argc, char **argv)
+{
+ ubit_t exp[114];
+ ubit_t out[114];
+ int n, i;
+
+ for (n=0; n<3; n++) {
+ /* "Randomize" */
+ for (i=0; i<114; i++)
+ out[i] = i & 1;
+
+ /* DL */
+ osmo_pbit2ubit(exp, &dl[15*n], 114);
+
+ osmo_a5(n, key, fn, out, NULL);
+
+ printf("A5/%d - DL: %s", n, binstr(out, 114));
+
+ if (!memcmp(exp, out, 114))
+ printf(" => OK\n");
+ else {
+ printf(" => BAD\n");
+ printf(" Expected: %s", binstr(out, 114));
+ fprintf(stderr, "[!] A5/%d DL failed", n);
+ exit(1);
+ }
+
+ /* UL */
+ osmo_pbit2ubit(exp, &ul[15*n], 114);
+
+ osmo_a5(n, key, fn, NULL, out);
+
+ printf("A5/%d - UL: %s", n, binstr(out, 114));
+
+ if (!memcmp(exp, out, 114))
+ printf(" => OK\n");
+ else {
+ printf(" => BAD\n");
+ printf(" Expected: %s", binstr(out, 114));
+ fprintf(stderr, "[!] A5/%d UL failed", n);
+ exit(1);
+ }
+ }
+
+ return 0;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.ok b/Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.ok
new file mode 100644
index 0000000..4497e14
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/a5/a5_test.ok
@@ -0,0 +1,6 @@
+A5/0 - DL: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 => OK
+A5/0 - UL: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 => OK
+A5/1 - DL: 110010111010001001010101011101100001011101011101001110110001110001111011001011110010100110101000110000011011011000 => OK
+A5/1 - UL: 110110010000001101011110000011110010101011101100000100111001101000000101110101001010100001111011101100010110010010 => OK
+A5/2 - DL: 010001011001110010001000110000111000001010110111111111111011001110011000110100101111100101101110000011110001010010 => OK
+A5/2 - UL: 111100000011101010101100110111101110001101011011010111100110010110000000101110101010101111000000010110010010011001 => OK
diff --git a/Src/osmolib/src/shared/libosmocore/tests/auth/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/auth/Makefile.am
new file mode 100644
index 0000000..52976d0
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/auth/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+noinst_PROGRAMS = milenage_test
+EXTRA_DIST = milenage_test.ok
+
+milenage_test_SOURCES = milenage_test.c
+milenage_test_LDADD = $(top_builddir)/src/libosmocore.la \
+ $(top_builddir)/src/gsm/libosmogsm.la
+
diff --git a/Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.c b/Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.c
new file mode 100644
index 0000000..da7c800
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.c
@@ -0,0 +1,78 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <osmocom/crypt/auth.h>
+#include <osmocom/core/utils.h>
+
+static void dump_auth_vec(struct osmo_auth_vector *vec)
+{
+ printf("RAND:\t%s\n", osmo_hexdump(vec->rand, sizeof(vec->rand)));
+
+ if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) {
+ printf("AUTN:\t%s\n", osmo_hexdump(vec->autn, sizeof(vec->autn)));
+ printf("IK:\t%s\n", osmo_hexdump(vec->ik, sizeof(vec->ik)));
+ printf("CK:\t%s\n", osmo_hexdump(vec->ck, sizeof(vec->ck)));
+ printf("RES:\t%s\n", osmo_hexdump(vec->res, vec->res_len));
+ }
+
+ if (vec->auth_types & OSMO_AUTH_TYPE_GSM) {
+ printf("SRES:\t%s\n", osmo_hexdump(vec->sres, sizeof(vec->sres)));
+ printf("Kc:\t%s\n", osmo_hexdump(vec->kc, sizeof(vec->kc)));
+ }
+}
+
+static struct osmo_sub_auth_data test_aud = {
+ .type = OSMO_AUTH_TYPE_UMTS,
+ .algo = OSMO_AUTH_ALG_MILENAGE,
+ .u.umts = {
+ .opc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ .k = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ .amf = { 0x00, 0x00 },
+ .sqn = 0x22,
+ },
+};
+
+int main(int argc, char **argv)
+{
+ struct osmo_auth_vector _vec;
+ struct osmo_auth_vector *vec = &_vec;
+ uint8_t _rand[16];
+ int rc;
+
+#if 0
+ srand(time(NULL));
+ *(uint32_t *)&_rand[0] = rand();
+ *(uint32_t *)(&_rand[4]) = rand();
+ *(uint32_t *)(&_rand[8]) = rand();
+ *(uint32_t *)(&_rand[12]) = rand();
+#else
+ memset(_rand, 0, sizeof(_rand));
+#endif
+ memset(vec, 0, sizeof(*vec));
+
+ rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
+ if (rc < 0) {
+ fprintf(stderr, "error generating auth vector\n");
+ exit(1);
+ }
+
+ dump_auth_vec(vec);
+
+ const uint8_t auts[14] = { 0x87, 0x11, 0xa0, 0xec, 0x9e, 0x16, 0x37, 0xdf,
+ 0x17, 0xf8, 0x0b, 0x38, 0x4e, 0xe4 };
+
+ rc = osmo_auth_gen_vec_auts(vec, &test_aud, auts, _rand, _rand);
+ if (rc < 0) {
+ printf("AUTS failed\n");
+ } else {
+ printf("AUTS success: SEQ.MS = %lu\n", test_aud.u.umts.sqn);
+ }
+
+ exit(0);
+
+}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.ok b/Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.ok
new file mode 100644
index 0000000..66337ca
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/auth/milenage_test.ok
@@ -0,0 +1,8 @@
+RAND: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+AUTN: ec 93 20 c2 c2 12 00 00 c8 b7 de 2a 34 49 f1 bd
+IK: 12 cb 2d d3 e0 ec 83 78 f6 fc 1d 60 6c 61 9f 47
+CK: 72 00 a1 84 d8 f2 c7 58 fb df 87 90 0d db f2 75
+RES: e9 fc 88 cc c8 a3 53 81
+SRES: 21 5f db 4d
+Kc: 6d e8 16 a7 59 a4 29 12
+AUTS success: SEQ.MS = 33
diff --git a/Src/osmolib/src/shared/libosmocore/tests/bits/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/bits/Makefile.am
index dd03e83..d6fb2f2 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/bits/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/bits/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = bitrev_test
+EXTRA_DIST = bitrev_test.ok
bitrev_test_SOURCES = bitrev_test.c
bitrev_test_LDADD = $(top_builddir)/src/libosmocore.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/bits/bitrev_test.ok b/Src/osmolib/src/shared/libosmocore/tests/bits/bitrev_test.ok
new file mode 100644
index 0000000..47f402f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/bits/bitrev_test.ok
@@ -0,0 +1,24 @@
+INORDER: 01 02 04 08 10 20 40 80
+REVERSED: 80 40 20 10 08 04 02 01
+
+INORDER: 02 04 08 10 20 40 80
+REVERSED: 40 20 10 08 04 02 01
+
+INORDER: 04 08 10 20 40 80
+REVERSED: 20 10 08 04 02 01
+
+INORDER: 08 10 20 40 80
+REVERSED: 10 08 04 02 01
+
+INORDER: 10 20 40 80
+REVERSED: 08 04 02 01
+
+INORDER: 20 40 80
+REVERSED: 04 02 01
+
+INORDER: 40 80
+REVERSED: 02 01
+
+INORDER: 80
+REVERSED: 01
+
diff --git a/Src/osmolib/src/shared/libosmocore/tests/conv/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/conv/Makefile.am
new file mode 100644
index 0000000..75cfec8
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/conv/Makefile.am
@@ -0,0 +1,6 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+noinst_PROGRAMS = conv_test
+EXTRA_DIST = conv_test.ok
+
+conv_test_SOURCES = conv_test.c
+conv_test_LDADD = $(top_builddir)/src/libosmocore.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.c b/Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.c
new file mode 100644
index 0000000..54e043e
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.c
@@ -0,0 +1,486 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/conv.h>
+#include <osmocom/core/utils.h>
+
+#define MAX_LEN_BITS 512
+#define MAX_LEN_BYTES (512/8)
+
+
+/* ------------------------------------------------------------------------ */
+/* Test codes */
+/* ------------------------------------------------------------------------ */
+
+/* GSM xCCH -> Non-recursive code, flushed, not punctured */
+static const uint8_t conv_gsm_xcch_next_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
+ { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
+};
+
+static const uint8_t conv_gsm_xcch_next_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+};
+
+static const struct osmo_conv_code conv_gsm_xcch = {
+ .N = 2,
+ .K = 5,
+ .len = 224,
+ .term = CONV_TERM_FLUSH,
+ .next_output = conv_gsm_xcch_next_output,
+ .next_state = conv_gsm_xcch_next_state,
+};
+
+
+/* GSM TCH/AFS 7.95 -> Recursive code, flushed, with puncturing */
+static const uint8_t conv_gsm_tch_afs_7_95_next_output[][2] = {
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
+ { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
+ { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
+ { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
+};
+
+static const uint8_t conv_gsm_tch_afs_7_95_next_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 5, 4 }, { 7, 6 },
+ { 9, 8 }, { 11, 10 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 21, 20 }, { 23, 22 },
+ { 25, 24 }, { 27, 26 }, { 28, 29 }, { 30, 31 },
+ { 33, 32 }, { 35, 34 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 45, 44 }, { 47, 46 },
+ { 49, 48 }, { 51, 50 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 61, 60 }, { 63, 62 },
+ { 1, 0 }, { 3, 2 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 13, 12 }, { 15, 14 },
+ { 17, 16 }, { 19, 18 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 29, 28 }, { 31, 30 },
+ { 32, 33 }, { 34, 35 }, { 37, 36 }, { 39, 38 },
+ { 41, 40 }, { 43, 42 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 53, 52 }, { 55, 54 },
+ { 57, 56 }, { 59, 58 }, { 60, 61 }, { 62, 63 },
+};
+
+static const uint8_t conv_gsm_tch_afs_7_95_next_term_output[] = {
+ 0, 3, 5, 6, 5, 6, 0, 3, 3, 0, 6, 5, 6, 5, 3, 0,
+ 4, 7, 1, 2, 1, 2, 4, 7, 7, 4, 2, 1, 2, 1, 7, 4,
+ 7, 4, 2, 1, 2, 1, 7, 4, 4, 7, 1, 2, 1, 2, 4, 7,
+ 3, 0, 6, 5, 6, 5, 3, 0, 0, 3, 5, 6, 5, 6, 0, 3,
+};
+
+static const uint8_t conv_gsm_tch_afs_7_95_next_term_state[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+};
+
+static int conv_gsm_tch_afs_7_95_puncture[] = {
+ 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
+ 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
+ 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
+ 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
+ 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
+ 506, 508, 509, 511, 512,
+ -1, /* end */
+};
+
+static const struct osmo_conv_code conv_gsm_tch_afs_7_95 = {
+ .N = 3,
+ .K = 7,
+ .len = 165,
+ .term = CONV_TERM_FLUSH,
+ .next_output = conv_gsm_tch_afs_7_95_next_output,
+ .next_state = conv_gsm_tch_afs_7_95_next_state,
+ .next_term_output = conv_gsm_tch_afs_7_95_next_term_output,
+ .next_term_state = conv_gsm_tch_afs_7_95_next_term_state,
+ .puncture = conv_gsm_tch_afs_7_95_puncture,
+};
+
+
+/* GMR-1 TCH3 Speech -> Non recursive code, tail-biting, punctured */
+static const uint8_t conv_gmr1_tch3_speech_next_output[][2] = {
+ { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
+ { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
+ { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
+ { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
+ { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
+ { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
+ { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
+ { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
+ { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
+ { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
+ { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
+ { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
+};
+
+static const uint8_t conv_gmr1_tch3_speech_next_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const int conv_gmr1_tch3_speech_puncture[] = {
+ 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47,
+ 51, 55, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95,
+ -1, /* end */
+};
+
+static const struct osmo_conv_code conv_gmr1_tch3_speech = {
+ .N = 2,
+ .K = 7,
+ .len = 48,
+ .term = CONV_TERM_TAIL_BITING,
+ .next_output = conv_gmr1_tch3_speech_next_output,
+ .next_state = conv_gmr1_tch3_speech_next_state,
+ .puncture = conv_gmr1_tch3_speech_puncture,
+};
+
+
+/* WiMax FCH -> Non recursive code, tail-biting, non-punctured */
+static const uint8_t conv_wimax_fch_next_output[][2] = {
+ { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
+ { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
+ { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
+ { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
+ { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
+ { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
+ { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
+ { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
+ { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
+ { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
+ { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
+ { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
+ { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
+ { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
+ { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
+ { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
+};
+
+static const uint8_t conv_wimax_fch_next_state[][2] = {
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
+ { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
+ { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
+ { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
+ { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
+ { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
+ { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
+ { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
+};
+
+static const struct osmo_conv_code conv_wimax_fch = {
+ .N = 2,
+ .K = 7,
+ .len = 48,
+ .term = CONV_TERM_TAIL_BITING,
+ .next_output = conv_wimax_fch_next_output,
+ .next_state = conv_wimax_fch_next_state,
+};
+
+
+/* Random code -> Non recursive code, direct truncation, non-punctured */
+static const struct osmo_conv_code conv_trunc = {
+ .N = 2,
+ .K = 5,
+ .len = 224,
+ .term = CONV_TERM_TRUNCATION,
+ .next_output = conv_gsm_xcch_next_output,
+ .next_state = conv_gsm_xcch_next_state,
+};
+
+
+/* ------------------------------------------------------------------------ */
+/* Test vectors */
+/* ------------------------------------------------------------------------ */
+
+struct conv_test_vector {
+ const char *name;
+ const struct osmo_conv_code *code;
+ int in_len;
+ int out_len;
+ int has_vec;
+ pbit_t vec_in[MAX_LEN_BYTES];
+ pbit_t vec_out[MAX_LEN_BYTES];
+};
+
+static const struct conv_test_vector tests[] = {
+ {
+ .name = "GSM xCCH (non-recursive, flushed, not punctured)",
+ .code = &conv_gsm_xcch,
+ .in_len = 224,
+ .out_len = 456,
+ .has_vec = 1,
+ .vec_in = { 0xf3, 0x1d, 0xb4, 0x0c, 0x4d, 0x1d, 0x9d, 0xae,
+ 0xc0, 0x0a, 0x42, 0x57, 0x13, 0x60, 0x80, 0x96,
+ 0xef, 0x23, 0x7e, 0x4c, 0x1d, 0x96, 0x24, 0x19,
+ 0x17, 0xf2, 0x44, 0x99 },
+ .vec_out = { 0xe9, 0x4d, 0x70, 0xab, 0xa2, 0x87, 0xf0, 0xe7,
+ 0x04, 0x14, 0x7c, 0xab, 0xaf, 0x6b, 0xa1, 0x16,
+ 0xeb, 0x30, 0x00, 0xde, 0xc8, 0xfd, 0x0b, 0x85,
+ 0x80, 0x41, 0x4a, 0xcc, 0xd3, 0xc0, 0xd0, 0xb6,
+ 0x26, 0xe5, 0x4e, 0x32, 0x49, 0x69, 0x38, 0x17,
+ 0x33, 0xab, 0xaf, 0xb6, 0xc1, 0x08, 0xf3, 0x9f,
+ 0x8c, 0x75, 0x6a, 0x4e, 0x08, 0xc4, 0x20, 0x5f,
+ 0x8f },
+ },
+ {
+ .name = "GSM TCH/AFS 7.95 (recursive, flushed, punctured)",
+ .code = &conv_gsm_tch_afs_7_95,
+ .in_len = 165,
+ .out_len = 448,
+ .has_vec = 1,
+ .vec_in = { 0x87, 0x66, 0xc3, 0x58, 0x09, 0xd4, 0x06, 0x59,
+ 0x10, 0xbf, 0x6b, 0x7f, 0xc8, 0xed, 0x72, 0xaa,
+ 0xc1, 0x3d, 0xf3, 0x1e, 0xb0 },
+ .vec_out = { 0x92, 0xbc, 0xde, 0xa0, 0xde, 0xbe, 0x01, 0x2f,
+ 0xbe, 0xe4, 0x61, 0x32, 0x4d, 0x4f, 0xdc, 0x41,
+ 0x43, 0x0d, 0x15, 0xe0, 0x23, 0xdd, 0x18, 0x91,
+ 0xe5, 0x36, 0x2d, 0xb7, 0xd9, 0x78, 0xb8, 0xb1,
+ 0xb7, 0xcb, 0x2f, 0xc0, 0x52, 0x8f, 0xe2, 0x8c,
+ 0x6f, 0xa6, 0x79, 0x88, 0xed, 0x0c, 0x2e, 0x9e,
+ 0xa1, 0x5f, 0x45, 0x4a, 0xfb, 0xe6, 0x5a, 0x9c },
+ },
+ {
+ .name = "GMR-1 TCH3 Speech (non-recursive, tail-biting, punctured)",
+ .code = &conv_gmr1_tch3_speech,
+ .in_len = 48,
+ .out_len = 72,
+ .has_vec = 1,
+ .vec_in = { 0x4d, 0xcb, 0xfc, 0x72, 0xf4, 0x8c },
+ .vec_out = { 0xc0, 0x86, 0x63, 0x4b, 0x8b, 0xd4, 0x6a, 0x76, 0xb2 },
+ },
+ {
+ .name = "WiMax FCH (non-recursive, tail-biting, not punctured)",
+ .code = &conv_wimax_fch,
+ .in_len = 48,
+ .out_len = 96,
+ .has_vec = 1,
+ .vec_in = { 0xfc, 0xa0, 0xa0, 0xfc, 0xa0, 0xa0 },
+ .vec_out = { 0x19, 0x42, 0x8a, 0xed, 0x21, 0xed, 0x19, 0x42,
+ 0x8a, 0xed, 0x21, 0xed },
+ },
+ {
+ .name = "??? (non-recursive, direct truncation, not punctured)",
+ .code = &conv_trunc,
+ .in_len = 224,
+ .out_len = 448,
+ .has_vec = 1,
+ .vec_in = { 0xe5, 0xe0, 0x85, 0x7e, 0xf7, 0x08, 0x19, 0x5a,
+ 0xb9, 0xad, 0x82, 0x37, 0x98, 0x8b, 0x26, 0xb9,
+ 0x81, 0x26, 0x9c, 0x75, 0xaf, 0xf3, 0xcb, 0x07,
+ 0xac, 0x63, 0xe2, 0x9c,
+ },
+ .vec_out = { 0xea, 0x3b, 0x55, 0x0c, 0xd3, 0xf7, 0x85, 0x69,
+ 0xe5, 0x79, 0x83, 0xd3, 0xc3, 0x9f, 0xb8, 0x61,
+ 0x21, 0x63, 0x51, 0x18, 0xac, 0xcd, 0x32, 0x49,
+ 0x53, 0x5c, 0x13, 0x1d, 0xbe, 0x05, 0x11, 0x63,
+ 0x5c, 0xc3, 0x42, 0x05, 0x1c, 0x68, 0x0a, 0xb4,
+ 0x61, 0x15, 0xaa, 0x4d, 0x94, 0xed, 0xb3, 0x3a,
+ 0x5d, 0x1b, 0x09, 0xc2, 0x99, 0x01, 0xec, 0x68 },
+ },
+ { /* end */ },
+};
+
+
+
+
+/* ------------------------------------------------------------------------ */
+/* Main */
+/* ------------------------------------------------------------------------ */
+
+static void
+fill_random(ubit_t *b, int n)
+{
+ int i;
+ for (i=0; i<n; i++)
+ b[i] = random() & 1;
+}
+
+static void
+ubit_to_sbit(sbit_t *dst, ubit_t *src, int n)
+{
+ int i;
+ for (i=0; i<n; i++)
+ dst[i] = src[i] ? -127 : 127;
+}
+
+static void
+sbit_to_ubit(ubit_t *dst, sbit_t *src, int n)
+{
+ int i;
+ for (i=0; i<n; i++)
+ dst[i] = src[i] < 0;
+}
+
+
+int main(int argc, char argv[])
+{
+ const struct conv_test_vector *tst;
+ ubit_t *bu0, *bu1;
+ sbit_t *bs;
+
+ srandom(time(NULL));
+
+ bu0 = malloc(sizeof(ubit_t) * MAX_LEN_BITS);
+ bu1 = malloc(sizeof(ubit_t) * MAX_LEN_BITS);
+ bs = malloc(sizeof(sbit_t) * MAX_LEN_BITS);
+
+ for (tst=tests; tst->name; tst++)
+ {
+ int i,l;
+
+ /* Test name */
+ printf("[+] Testing: %s\n", tst->name);
+
+ /* Check length */
+ l = osmo_conv_get_input_length(tst->code, 0);
+ printf("[.] Input length : ret = %3d exp = %3d -> %s\n",
+ l, tst->in_len, l == tst->in_len ? "OK" : "Bad !");
+
+ if (l != tst->in_len) {
+ fprintf(stderr, "[!] Failure for input length computation\n");
+ return -1;
+ }
+
+ l = osmo_conv_get_output_length(tst->code, 0);
+ printf("[.] Output length : ret = %3d exp = %3d -> %s\n",
+ l, tst->out_len, l == tst->out_len ? "OK" : "Bad !");
+
+ if (l != tst->out_len) {
+ fprintf(stderr, "[!] Failure for output length computation\n");
+ return -1;
+ }
+
+ /* Check pre-computed vector */
+ if (tst->has_vec) {
+ printf("[.] Pre computed vector checks:\n");
+
+ printf("[..] Encoding: ");
+
+ osmo_pbit2ubit(bu0, tst->vec_in, tst->in_len);
+
+ l = osmo_conv_encode(tst->code, bu0, bu1);
+ if (l != tst->out_len) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed encoding length check\n");
+ return -1;
+ }
+
+ osmo_pbit2ubit(bu0, tst->vec_out, tst->out_len);
+
+ if (memcmp(bu0, bu1, tst->out_len)) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed encoding: Results don't match\n");
+ return -1;
+ };
+
+ printf("OK\n");
+
+
+ printf("[..] Decoding: ");
+
+ ubit_to_sbit(bs, bu0, l);
+
+ l = osmo_conv_decode(tst->code, bs, bu1);
+ if (l != 0) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed decoding: non-zero path (%d)\n", l);
+ return -1;
+ }
+
+ osmo_pbit2ubit(bu0, tst->vec_in, tst->in_len);
+
+ if (memcmp(bu0, bu1, tst->in_len)) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed decoding: Results don't match\n");
+ return -1;
+ }
+
+ printf("OK\n");
+ }
+
+ /* Check random vector */
+ printf("[.] Random vector checks:\n");
+
+ for (i=0; i<3; i++) {
+ printf("[..] Encoding / Decoding cycle : ");
+
+ fill_random(bu0, tst->in_len);
+
+ l = osmo_conv_encode(tst->code, bu0, bu1);
+ if (l != tst->out_len) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed encoding length check\n");
+ return -1;
+ }
+
+ ubit_to_sbit(bs, bu1, l);
+
+ l = osmo_conv_decode(tst->code, bs, bu1);
+ if (l != 0) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed decoding: non-zero path (%d)\n", l);
+ return -1;
+ }
+
+ if (memcmp(bu0, bu1, tst->in_len)) {
+ printf("ERROR !\n");
+ fprintf(stderr, "[!] Failed decoding: Results don't match\n");
+ return -1;
+ }
+
+ printf("OK\n");
+ }
+
+ /* Spacing */
+ printf("\n");
+ }
+
+ free(bs);
+ free(bu1);
+ free(bu0);
+
+ return 0;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.ok b/Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.ok
new file mode 100644
index 0000000..2122961
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/conv/conv_test.ok
@@ -0,0 +1,55 @@
+[+] Testing: GSM xCCH (non-recursive, flushed, not punctured)
+[.] Input length : ret = 224 exp = 224 -> OK
+[.] Output length : ret = 456 exp = 456 -> OK
+[.] Pre computed vector checks:
+[..] Encoding: OK
+[..] Decoding: OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: GSM TCH/AFS 7.95 (recursive, flushed, punctured)
+[.] Input length : ret = 165 exp = 165 -> OK
+[.] Output length : ret = 448 exp = 448 -> OK
+[.] Pre computed vector checks:
+[..] Encoding: OK
+[..] Decoding: OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: GMR-1 TCH3 Speech (non-recursive, tail-biting, punctured)
+[.] Input length : ret = 48 exp = 48 -> OK
+[.] Output length : ret = 72 exp = 72 -> OK
+[.] Pre computed vector checks:
+[..] Encoding: OK
+[..] Decoding: OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: WiMax FCH (non-recursive, tail-biting, not punctured)
+[.] Input length : ret = 48 exp = 48 -> OK
+[.] Output length : ret = 96 exp = 96 -> OK
+[.] Pre computed vector checks:
+[..] Encoding: OK
+[..] Decoding: OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: ??? (non-recursive, direct truncation, not punctured)
+[.] Input length : ret = 224 exp = 224 -> OK
+[.] Output length : ret = 448 exp = 448 -> OK
+[.] Pre computed vector checks:
+[..] Encoding: OK
+[..] Decoding: OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
diff --git a/Src/osmolib/src/shared/libosmocore/tests/gsm0808/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/gsm0808/Makefile.am
new file mode 100644
index 0000000..a238e7f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/gsm0808/Makefile.am
@@ -0,0 +1,6 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+noinst_PROGRAMS = gsm0808_test
+EXTRA_DIST = gsm0808_test.ok
+
+gsm0808_test_SOURCES = gsm0808_test.c
+gsm0808_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.c b/Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.c
new file mode 100644
index 0000000..7e5e97b
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.c
@@ -0,0 +1,269 @@
+/*
+ * (C) 2012 by Holger Hans Peter Freyther
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocom/gsm/gsm0808.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define VERIFY(msg, data, len) \
+ if (msgb_l3len(msg) != len) { \
+ printf("%s:%d Length don't match: %d vs. %d. %s\n", \
+ __func__, __LINE__, msgb_l3len(msg), len, \
+ osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
+ abort(); \
+ } else if (memcmp(msg->l3h, data, len) != 0) { \
+ printf("%s:%d didn't match: got: %s\n", \
+ __func__, __LINE__, \
+ osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
+ abort(); \
+ }
+
+
+static void test_create_layer3(void)
+{
+ static const uint8_t res[] = {
+ 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
+ 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 };
+ struct msgb *msg, *in_msg;
+ printf("Testing creating Layer3\n");
+
+ in_msg = msgb_alloc_headroom(512, 128, "foo");
+ in_msg->l3h = in_msg->data;
+ msgb_v_put(in_msg, 0x23);
+
+ msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+ msgb_free(in_msg);
+}
+
+static void test_create_reset()
+{
+ static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
+ struct msgb *msg;
+
+ printf("Testing creating Reset\n");
+ msg = gsm0808_create_reset();
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+}
+
+static void test_create_clear_command()
+{
+ static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
+ struct msgb *msg;
+
+ printf("Testing creating Clear Command\n");
+ msg = gsm0808_create_clear_command(0x23);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+}
+
+static void test_create_clear_complete()
+{
+ static const uint8_t res[] = { 0x00, 0x01, 0x21 };
+ struct msgb *msg;
+
+ printf("Testing creating Clear Complete\n");
+ msg = gsm0808_create_clear_complete();
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+}
+
+static void test_create_cipher_complete()
+{
+ static const uint8_t res1[] = {
+ 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
+ static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
+ struct msgb *l3, *msg;
+
+ printf("Testing creating Cipher Complete\n");
+ l3 = msgb_alloc_headroom(512, 128, "l3h");
+ l3->l3h = l3->data;
+ msgb_v_put(l3, 0x23);
+ msgb_v_put(l3, 0x42);
+ msgb_v_put(l3, 0x21);
+
+ /* with l3 data */
+ msg = gsm0808_create_cipher_complete(l3, 4);
+ VERIFY(msg, res1, ARRAY_SIZE(res1));
+ msgb_free(msg);
+
+ /* with l3 data but short */
+ l3->len -= 1;
+ l3->tail -= 1;
+ msg = gsm0808_create_cipher_complete(l3, 4);
+ VERIFY(msg, res2, ARRAY_SIZE(res2));
+ msgb_free(msg);
+
+ /* without l3 data */
+ msg = gsm0808_create_cipher_complete(NULL, 4);
+ VERIFY(msg, res2, ARRAY_SIZE(res2));
+ msgb_free(msg);
+
+
+ msgb_free(l3);
+}
+
+static void test_create_cipher_reject()
+{
+ static const uint8_t res[] = { 0x00, 0x02, 0x59, 0x23 };
+ struct msgb *msg;
+
+ printf("Testing creating Cipher Reject\n");
+ msg = gsm0808_create_cipher_reject(0x23);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+}
+
+static void test_create_cm_u()
+{
+ static const uint8_t res[] = {
+ 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
+ static const uint8_t res2o[] = {
+ 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
+ struct msgb *msg;
+ const uint8_t cm2 = 0x23;
+ const uint8_t cm3 = 0x42;
+
+ printf("Testing creating CM U\n");
+ msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+
+ msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
+ VERIFY(msg, res2o, ARRAY_SIZE(res2o));
+
+ msgb_free(msg);
+}
+
+static void test_create_sapi_reject()
+{
+ static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 };
+ struct msgb *msg;
+
+ printf("Testing creating SAPI Reject\n");
+ msg = gsm0808_create_sapi_reject(3);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+}
+
+static void test_create_ass_compl()
+{
+ static const uint8_t res1[] = {
+ 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
+ 0x11, 0x40, 0x22 };
+ static const uint8_t res2[] = {
+ 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
+ struct msgb *msg;
+
+ printf("Testing creating Assignment Complete\n");
+ msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
+ VERIFY(msg, res1, ARRAY_SIZE(res1));
+ msgb_free(msg);
+
+ msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
+ VERIFY(msg, res2, ARRAY_SIZE(res2));
+ msgb_free(msg);
+}
+
+static void test_create_ass_fail()
+{
+ static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
+ static const uint8_t res2[] = {
+ 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
+ uint8_t rr_res = 2;
+ struct msgb *msg;
+
+ printf("Testing creating Assignment Failure\n");
+ msg = gsm0808_create_assignment_failure(0x23, NULL);
+ VERIFY(msg, res1, ARRAY_SIZE(res1));
+ msgb_free(msg);
+
+ msg = gsm0808_create_assignment_failure(0x23, &rr_res);
+ VERIFY(msg, res2, ARRAY_SIZE(res2));
+ msgb_free(msg);
+}
+
+static void test_create_clear_rqst()
+{
+ static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
+ struct msgb *msg;
+
+ printf("Testing creating Clear Request\n");
+ msg = gsm0808_create_clear_rqst(0x23);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+}
+
+static void test_create_dtap()
+{
+ static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
+ struct msgb *msg, *l3;
+
+ printf("Testing creating DTAP\n");
+ l3 = msgb_alloc_headroom(512, 128, "test");
+ l3->l3h = l3->data;
+ msgb_v_put(l3, 0x23);
+ msgb_v_put(l3, 0x42);
+
+ msg = gsm0808_create_dtap(l3, 0x3);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+ msgb_free(l3);
+}
+
+static void test_prepend_dtap()
+{
+ static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
+ struct msgb *in_msg;
+
+ printf("Testing prepend DTAP\n");
+
+ in_msg = msgb_alloc_headroom(512, 128, "test");
+ msgb_v_put(in_msg, 0x23);
+ msgb_v_put(in_msg, 0x42);
+
+ gsm0808_prepend_dtap_header(in_msg, 0x3);
+ in_msg->l3h = in_msg->data;
+ VERIFY(in_msg, res, ARRAY_SIZE(res));
+ msgb_free(in_msg);
+}
+
+int main(int argc, char **argv)
+{
+ printf("Testing generation of GSM0808 messages\n");
+ test_create_layer3();
+ test_create_reset();
+ test_create_clear_command();
+ test_create_clear_complete();
+ test_create_cipher_complete();
+ test_create_cipher_reject();
+ test_create_cm_u();
+ test_create_sapi_reject();
+ test_create_ass_compl();
+ test_create_ass_fail();
+ test_create_clear_rqst();
+ test_create_dtap();
+ test_prepend_dtap();
+
+ printf("Done\n");
+ return EXIT_SUCCESS;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.ok b/Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.ok
new file mode 100644
index 0000000..eb43126
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/gsm0808/gsm0808_test.ok
@@ -0,0 +1,15 @@
+Testing generation of GSM0808 messages
+Testing creating Layer3
+Testing creating Reset
+Testing creating Clear Command
+Testing creating Clear Complete
+Testing creating Cipher Complete
+Testing creating Cipher Reject
+Testing creating CM U
+Testing creating SAPI Reject
+Testing creating Assignment Complete
+Testing creating Assignment Failure
+Testing creating Clear Request
+Testing creating DTAP
+Testing prepend DTAP
+Done
diff --git a/Src/osmolib/src/shared/libosmocore/tests/lapd/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/lapd/Makefile.am
new file mode 100644
index 0000000..f7e2ab0
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/lapd/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include
+AM_FLAGS = -Wall -O0
+noinst_PROGRAMS = lapd_test
+EXTRA_DIST = lapd_test.ok
+
+lapd_test_SOURCES = lapd_test.c
+lapd_test_LDADD = \
+ $(top_builddir)/src/libosmocore.la \
+ $(top_builddir)/src/gsm/libosmogsm.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.c b/Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.c
new file mode 100644
index 0000000..d58bec6
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.c
@@ -0,0 +1,319 @@
+/*
+ * (C) 2011 by Holger Hans Peter Freyther
+ * (C) 2011 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocom/core/logging.h>
+#include <osmocom/gsm/lapdm.h>
+#include <osmocom/gsm/rsl.h>
+
+#include <errno.h>
+
+#include <string.h>
+
+#define CHECK_RC(rc) \
+ if (rc != 0) { \
+ printf("Operation failed rc=%d on %s:%d\n", rc, __FILE__, __LINE__); \
+ abort(); \
+ }
+
+#define ASSERT(exp) \
+ if (!(exp)) { \
+ printf("Assert failed %s %s:%d\n", #exp, __FILE__, __LINE__); \
+ abort(); \
+ }
+
+
+static struct log_info info = {};
+
+struct lapdm_polling_state {
+ struct lapdm_channel *bts;
+ int bts_read;
+
+ struct lapdm_channel *ms;
+ int ms_read;
+};
+
+static struct msgb *msgb_from_array(const uint8_t *data, int len)
+{
+ struct msgb *msg = msgb_alloc_headroom(4096, 128, "data");
+ msg->l3h = msgb_put(msg, len);
+ memcpy(msg->l3h, data, len);
+ return msg;
+}
+
+/*
+ * Test data is below...
+ */
+static const uint8_t cm[] = {
+ 0x05, 0x24, 0x31, 0x03, 0x50, 0x18, 0x93, 0x08,
+ 0x29, 0x47, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+};
+
+static const uint8_t cm_padded[] = {
+ 0x05, 0x24, 0x31, 0x03, 0x50, 0x18, 0x93, 0x08,
+ 0x29, 0x47, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x2b, 0x2b, 0x2b, 0x2b
+};
+
+static const uint8_t mm[] = {
+ 0x00, 0x0c, 0x00, 0x03, 0x01, 0x01, 0x20, 0x02,
+ 0x00, 0x0b, 0x00, 0x03, 0x05, 0x04, 0x0d
+};
+
+static const uint8_t dummy1[] = {
+ 0xab, 0x03, 0x30, 0x60, 0x06,
+};
+
+static struct msgb *create_cm_serv_req(void)
+{
+ struct msgb *msg;
+
+ msg = msgb_from_array(cm, sizeof(cm));
+ rsl_rll_push_l3(msg, RSL_MT_EST_REQ, 0, 0, 1);
+ return msg;
+}
+
+static struct msgb *create_mm_id_req(void)
+{
+ struct msgb *msg;
+
+ msg = msgb_from_array(mm, sizeof(mm));
+ msg->l2h = msg->data + 3;
+ ASSERT(msgb_l2len(msg) == 12);
+ msg->l3h = msg->l2h + 6;
+ ASSERT(msgb_l3len(msg) == 6);
+
+ return msg;
+}
+
+static struct msgb *create_empty_msg(void)
+{
+ struct msgb *msg;
+
+ msg = msgb_from_array(NULL, 0);
+ ASSERT(msgb_l3len(msg) == 0);
+ rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1);
+ return msg;
+}
+
+static struct msgb *create_dummy_data_req(void)
+{
+ struct msgb *msg;
+
+ msg = msgb_from_array(dummy1, sizeof(dummy1));
+ rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1);
+ return msg;
+}
+
+static int send(struct msgb *in_msg, struct lapdm_channel *chan)
+{
+ struct osmo_phsap_prim pp;
+ struct msgb *msg;
+ int rc;
+
+ msg = msgb_alloc_headroom(128, 64, "PH-DATA.ind");
+ osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
+ PRIM_OP_INDICATION, msg);
+ /* copy over actual MAC block */
+ msg->l2h = msgb_put(msg, msgb_l2len(in_msg));
+ memcpy(msg->l2h, in_msg->l2h, msgb_l2len(in_msg));
+
+ /* LAPDm requires those... */
+ pp.u.data.chan_nr = 0;
+ pp.u.data.link_id = 0;
+ /* feed into the LAPDm code of libosmogsm */
+ rc = lapdm_phsap_up(&pp.oph, &chan->lapdm_dcch);
+ ASSERT(rc == 0 || rc == -EBUSY);
+ return 0;
+}
+
+/*
+ * I get called from the LAPDm code when something was sent my way...
+ */
+static int bts_to_ms_tx_cb(struct msgb *in_msg, struct lapdm_entity *le, void *_ctx)
+{
+ struct lapdm_polling_state *state = _ctx;
+
+
+ printf("%s: MS->BTS(us) message %d\n", __func__, msgb_length(in_msg));
+
+
+ if (state->bts_read == 0) {
+ printf("BTS: Verifying CM request.\n");
+ ASSERT(msgb_l3len(in_msg) == ARRAY_SIZE(cm_padded));
+ ASSERT(memcmp(in_msg->l3h, cm_padded, ARRAY_SIZE(cm_padded)) == 0);
+ } else if (state->bts_read == 1) {
+ printf("BTS: Verifying dummy message.\n");
+ ASSERT(msgb_l3len(in_msg) == ARRAY_SIZE(dummy1));
+ ASSERT(memcmp(in_msg->l3h, dummy1, ARRAY_SIZE(dummy1)) == 0);
+ } else {
+ printf("BTS: Do not know to verify: %d\n", state->bts_read);
+ }
+
+ state->bts_read += 1;
+ msgb_free(in_msg);
+
+ return 0;
+}
+
+static int ms_to_bts_l1_cb(struct osmo_prim_hdr *oph, void *_ctx)
+{
+ int rc;
+ struct lapdm_polling_state *state = _ctx;
+ printf("%s: MS(us) -> BTS prim message\n", __func__);
+
+ /* i stuff it into the LAPDm channel of the BTS */
+ rc = send(oph->msg, state->bts);
+ msgb_free(oph->msg);
+}
+
+static int ms_to_bts_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *_ctx)
+{
+ struct lapdm_polling_state *state = _ctx;
+
+ printf("%s: BTS->MS(us) message %d\n", __func__, msgb_length(msg));
+
+ if (state->ms_read == 0) {
+ struct abis_rsl_rll_hdr hdr;
+
+ printf("MS: Verifying incoming primitive.\n");
+ ASSERT(msg->len == sizeof(struct abis_rsl_rll_hdr) + 3);
+
+ /* verify the header */
+ memset(&hdr, 0, sizeof(hdr));
+ rsl_init_rll_hdr(&hdr, RSL_MT_EST_CONF);
+ hdr.c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
+ ASSERT(memcmp(msg->data, &hdr, sizeof(hdr)) == 0);
+
+ /* Verify the added RSL_IE_L3_INFO but we have a bug here */
+ ASSERT(msg->data[6] == RSL_IE_L3_INFO);
+ #warning "RSL_IE_L3_INFO 16 bit length is wrong"
+ /* ASSERT(msg->data[7] == 0x0 && msg->data[8] == 0x9c); */
+ /* this should be 0x0 and 0x0... but we have a bug */
+ } else if (state->ms_read == 1) {
+ printf("MS: Verifying incoming MM message: %d\n", msgb_l3len(msg));
+ ASSERT(msgb_l3len(msg) == 3);
+ ASSERT(memcmp(msg->l3h, &mm[12], msgb_l3len(msg)) == 0);
+ } else {
+ printf("MS: Do not know to verify: %d\n", state->ms_read);
+ }
+
+ state->ms_read += 1;
+ msgb_free(msg);
+ return 0;
+}
+
+static void test_lapdm_polling()
+{
+ printf("I do some very simple LAPDm test.\n");
+
+ int rc;
+ struct lapdm_polling_state test_state;
+ struct osmo_phsap_prim pp;
+
+ /* Configure LAPDm on both sides */
+ struct lapdm_channel bts_to_ms_channel;
+ struct lapdm_channel ms_to_bts_channel;
+ memset(&bts_to_ms_channel, 0, sizeof(bts_to_ms_channel));
+ memset(&ms_to_bts_channel, 0, sizeof(ms_to_bts_channel));
+
+ memset(&test_state, 0, sizeof(test_state));
+ test_state.bts = &bts_to_ms_channel;
+ test_state.ms = &ms_to_bts_channel;
+
+ /* BTS to MS in polling mode */
+ lapdm_channel_init(&bts_to_ms_channel, LAPDM_MODE_BTS);
+ lapdm_channel_set_flags(&bts_to_ms_channel, LAPDM_ENT_F_POLLING_ONLY);
+ lapdm_channel_set_l1(&bts_to_ms_channel, NULL, &test_state);
+ lapdm_channel_set_l3(&bts_to_ms_channel, bts_to_ms_tx_cb, &test_state);
+
+ /* MS to BTS in direct mode */
+ lapdm_channel_init(&ms_to_bts_channel, LAPDM_MODE_MS);
+ lapdm_channel_set_l1(&ms_to_bts_channel, ms_to_bts_l1_cb, &test_state);
+ lapdm_channel_set_l3(&ms_to_bts_channel, ms_to_bts_tx_cb, &test_state);
+
+ /*
+ * We try to send messages from the MS to the BTS to the MS..
+ */
+ /* 1. Start with MS -> BTS, BTS should have a pending message */
+ printf("Establishing link.\n");
+ lapdm_rslms_recvmsg(create_cm_serv_req(), &ms_to_bts_channel);
+
+ /* 2. Poll on the BTS for sending out a confirmation */
+ printf("\nConfirming\n");
+ ASSERT(test_state.bts_read == 1)
+ rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp);
+ CHECK_RC(rc);
+ ASSERT(pp.oph.msg->data == pp.oph.msg->l2h);
+ send(pp.oph.msg, &ms_to_bts_channel);
+ msgb_free(pp.oph.msg);
+ ASSERT(test_state.ms_read == 1);
+
+ /* 3. Send some data to the MS */
+ printf("\nSending back to MS\n");
+ lapdm_rslms_recvmsg(create_mm_id_req(), &bts_to_ms_channel);
+ rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp);
+ CHECK_RC(rc);
+ send(pp.oph.msg, &ms_to_bts_channel);
+ msgb_free(pp.oph.msg);
+ ASSERT(test_state.ms_read == 2);
+
+ /* verify that there is nothing more to poll */
+ rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp);
+ ASSERT(rc < 0);
+
+ /* 3. And back to the BTS */
+ printf("\nSending back to BTS\n");
+ ASSERT(test_state.ms_read == 2);
+ lapdm_rslms_recvmsg(create_dummy_data_req(), &ms_to_bts_channel);
+
+
+ /* 4. And back to the MS, but let's move data/l2h apart */
+ ASSERT(test_state.bts_read == 2)
+ ASSERT(test_state.ms_read == 2);
+ rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp);
+ CHECK_RC(rc);
+ send(pp.oph.msg, &ms_to_bts_channel);
+ ASSERT(test_state.ms_read == 2);
+ msgb_free(pp.oph.msg);
+
+ /* verify that there is nothing more to poll */
+ rc = lapdm_phsap_dequeue_prim(&bts_to_ms_channel.lapdm_dcch, &pp);
+ ASSERT(rc < 0);
+
+ /* check sending an empty L3 message fails */
+ rc = lapdm_rslms_recvmsg(create_empty_msg(), &bts_to_ms_channel);
+ ASSERT(rc == -1);
+ ASSERT(test_state.ms_read == 2);
+
+ /* clean up */
+ lapdm_channel_exit(&bts_to_ms_channel);
+ lapdm_channel_exit(&ms_to_bts_channel);
+}
+
+int main(int argc, char **argv)
+{
+ osmo_init_logging(&info);
+
+ test_lapdm_polling();
+ printf("Success.\n");
+
+ return 0;
+}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.ok b/Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.ok
new file mode 100644
index 0000000..d67a0a8
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/lapd/lapd_test.ok
@@ -0,0 +1,20 @@
+I do some very simple LAPDm test.
+Establishing link.
+ms_to_bts_l1_cb: MS(us) -> BTS prim message
+bts_to_ms_tx_cb: MS->BTS(us) message 29
+BTS: Verifying CM request.
+
+Confirming
+ms_to_bts_tx_cb: BTS->MS(us) message 9
+MS: Verifying incoming primitive.
+
+Sending back to MS
+ms_to_bts_tx_cb: BTS->MS(us) message 12
+MS: Verifying incoming MM message: 3
+ms_to_bts_l1_cb: MS(us) -> BTS prim message
+
+Sending back to BTS
+ms_to_bts_l1_cb: MS(us) -> BTS prim message
+bts_to_ms_tx_cb: MS->BTS(us) message 14
+BTS: Verifying dummy message.
+Success.
diff --git a/Src/osmolib/src/shared/libosmocore/tests/msgfile/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/msgfile/Makefile.am
index c9f4bec..88c355d 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/msgfile/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/msgfile/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = msgfile_test
+EXTRA_DIST = msgfile_test.ok msgconfig.cfg
msgfile_test_SOURCES = msgfile_test.c
msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/msgfile/msgfile_test.ok b/Src/osmolib/src/shared/libosmocore/tests/msgfile/msgfile_test.ok
new file mode 100644
index 0000000..c47cd74
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/msgfile/msgfile_test.ok
@@ -0,0 +1 @@
+Entry '*:*::Hello Welt'
diff --git a/Src/osmolib/src/shared/libosmocore/tests/sms/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/sms/Makefile.am
index fa4e387..02860af 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/sms/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/sms/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = sms_test
+EXTRA_DIST = sms_test.ok
sms_test_SOURCES = sms_test.c
sms_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/sms/sms_test.ok b/Src/osmolib/src/shared/libosmocore/tests/sms/sms_test.ok
new file mode 100644
index 0000000..d0e0983
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/sms/sms_test.ok
@@ -0,0 +1,2 @@
+SMS testing
+OK
diff --git a/Src/osmolib/src/shared/libosmocore/tests/smscb/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/smscb/Makefile.am
index 9a6fb4f..7045ea7 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/smscb/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/smscb/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = smscb_test
+EXTRA_DIST = smscb_test.ok
smscb_test_SOURCES = smscb_test.c
smscb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/smscb/smscb_test.ok b/Src/osmolib/src/shared/libosmocore/tests/smscb/smscb_test.ok
new file mode 100644
index 0000000..347037f
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/smscb/smscb_test.ok
@@ -0,0 +1,4 @@
+(srl) GS: 1 MSG_CODE: 1 UPDATE: 0
+(msg) msg_id: 1293
+(dcs) group: 1 language: 0
+(pge) page total: 1 current: 1
diff --git a/Src/osmolib/src/shared/libosmocore/tests/testsuite.at b/Src/osmolib/src/shared/libosmocore/tests/testsuite.at
new file mode 100644
index 0000000..69624c1
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/testsuite.at
@@ -0,0 +1,73 @@
+AT_INIT
+AT_BANNER([Regression tests.])
+
+
+# todo.. create one macro for it
+AT_SETUP([a5])
+AT_KEYWORDS([a5])
+cat $abs_srcdir/a5/a5_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [], [expout])
+AT_CLEANUP
+
+AT_SETUP([bits])
+AT_KEYWORDS([bits])
+cat $abs_srcdir/bits/bitrev_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/bits/bitrev_test], [], [expout])
+AT_CLEANUP
+
+AT_SETUP([conv])
+AT_KEYWORDS([conv])
+cat $abs_srcdir/conv/conv_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/conv/conv_test], [], [expout])
+AT_CLEANUP
+
+if ENABLE_MSGFILE
+AT_SETUP([msgfile])
+AT_KEYWORDS([msgfile])
+cp $abs_srcdir/msgfile/msgconfig.cfg .
+cat $abs_srcdir/msgfile/msgfile_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/msgfile/msgfile_test], [], [expout])
+AT_CLEANUP
+endif
+
+AT_SETUP([sms])
+AT_KEYWORDS([sms])
+cat $abs_srcdir/sms/sms_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/sms/sms_test], [], [expout])
+AT_CLEANUP
+
+AT_SETUP([smscb])
+AT_KEYWORDS([smscb])
+cat $abs_srcdir/smscb/smscb_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/smscb/smscb_test], [], [expout])
+AT_CLEANUP
+
+AT_SETUP([timer])
+AT_KEYWORDS([timer])
+cat $abs_srcdir/timer/timer_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/timer/timer_test -s 5], [], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([ussd])
+AT_KEYWORDS([ussd])
+cat $abs_srcdir/ussd/ussd_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/ussd/ussd_test], [], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([auth])
+AT_KEYWORDS([auth])
+cat $abs_srcdir/auth/milenage_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/auth/milenage_test], [], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([lapd])
+AT_KEYWORDS([lapd])
+cat $abs_srcdir/lapd/lapd_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/lapd/lapd_test], [], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([gsm0808])
+AT_KEYWORDS([gsm0808])
+cat $abs_srcdir/gsm0808/gsm0808_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gsm0808/gsm0808_test], [], [expout], [ignore])
+AT_CLEANUP
diff --git a/Src/osmolib/src/shared/libosmocore/tests/timer/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/timer/Makefile.am
index d3decf5..062d81b 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/timer/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/timer/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = timer_test
+EXTRA_DIST = timer_test.ok
timer_test_SOURCES = timer_test.c
timer_test_LDADD = $(top_builddir)/src/libosmocore.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.c b/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.c
index 240bc48..3775151 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.c
+++ b/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.c
@@ -1,7 +1,11 @@
/*
* (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2011 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
+ * Authors: Holger Hans Peter Freyther <zecke@selfish.org>
+ * Pablo Neira Ayuso <pablo@gnumonks.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -19,59 +23,169 @@
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <getopt.h>
+#include <osmocom/core/talloc.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/select.h>
+#include <osmocom/core/linuxlist.h>
#include "../../config.h"
-static void timer_fired(void *data);
+static void main_timer_fired(void *data);
+static void secondary_timer_fired(void *data);
-static struct osmo_timer_list timer_one = {
- .cb = timer_fired,
- .data = (void*)1,
+static unsigned int main_timer_step = 0;
+static struct osmo_timer_list main_timer = {
+ .cb = main_timer_fired,
+ .data = &main_timer_step,
};
-static struct osmo_timer_list timer_two = {
- .cb = timer_fired,
- .data = (void*)2,
-};
+static LLIST_HEAD(timer_test_list);
-static struct osmo_timer_list timer_three = {
- .cb = timer_fired,
- .data = (void*)3,
+struct test_timer {
+ struct llist_head head;
+ struct osmo_timer_list timer;
+ struct timeval start;
+ struct timeval stop;
};
-static void timer_fired(void *_data)
+/* number of test steps. We add fact(steps) timers in the whole test. */
+#define MAIN_TIMER_NSTEPS 16
+
+/* time between two steps, in secs. */
+#define TIME_BETWEEN_STEPS 1
+
+/* timer imprecision that we accept for this test: 10 milliseconds. */
+#define TIMER_PRES_SECS 0
+#define TIMER_PRES_USECS 10000
+
+static int timer_nsteps = MAIN_TIMER_NSTEPS;
+static unsigned int expired_timers = 0;
+static unsigned int total_timers = 0;
+static unsigned int too_late = 0;
+
+static void main_timer_fired(void *data)
{
- unsigned long data = (unsigned long) _data;
- printf("Fired timer: %lu\n", data);
-
- if (data == 1) {
- osmo_timer_schedule(&timer_one, 3, 0);
- osmo_timer_del(&timer_two);
- } else if (data == 2) {
- printf("Should not be fired... bug in del_timer\n");
- } else if (data == 3) {
- printf("Timer fired not registering again\n");
- } else {
- printf("wtf... wrong data\n");
- }
+ unsigned int *step = data;
+ unsigned int add_in_this_step;
+ int i;
+
+ if (*step == timer_nsteps) {
+ fprintf(stderr, "Main timer has finished, please, "
+ "wait a bit for the final report.\n");
+ return;
+ }
+ /* add 2^step pair of timers per step. */
+ add_in_this_step = (1 << *step);
+
+ for (i=0; i<add_in_this_step; i++) {
+ struct test_timer *v;
+
+ v = talloc_zero(NULL, struct test_timer);
+ if (v == NULL) {
+ fprintf(stderr, "timer_test: OOM!\n");
+ return;
+ }
+ gettimeofday(&v->start, NULL);
+ v->timer.cb = secondary_timer_fired;
+ v->timer.data = v;
+ unsigned int seconds = (random() % 10) + 1;
+ v->stop.tv_sec = v->start.tv_sec + seconds;
+ osmo_timer_schedule(&v->timer, seconds, 0);
+ llist_add(&v->head, &timer_test_list);
+ }
+ fprintf(stderr, "added %d timers in step %u (expired=%u)\n",
+ add_in_this_step, *step, expired_timers);
+ total_timers += add_in_this_step;
+ osmo_timer_schedule(&main_timer, TIME_BETWEEN_STEPS, 0);
+ (*step)++;
}
-int main(int argc, char** argv)
+static void secondary_timer_fired(void *data)
{
- printf("Starting... timer\n");
+ struct test_timer *v = data, *this, *tmp;
+ struct timeval current, res, precision = { 1, 0 };
+
+ gettimeofday(&current, NULL);
+
+ timersub(&current, &v->stop, &res);
+ if (timercmp(&res, &precision, >)) {
+ fprintf(stderr, "ERROR: timer %p has expired too late!\n",
+ v->timer);
+ too_late++;
+ }
+
+ llist_del(&v->head);
+ talloc_free(data);
+ expired_timers++;
+ if (expired_timers == total_timers) {
+ fprintf(stdout, "test over: added=%u expired=%u too_late=%u \n",
+ total_timers, expired_timers, too_late);
+ exit(EXIT_SUCCESS);
+ }
+
+ /* randomly (10%) deletion of timers. */
+ llist_for_each_entry_safe(this, tmp, &timer_test_list, head) {
+ if ((random() % 100) < 10) {
+ osmo_timer_del(&this->timer);
+ llist_del(&this->head);
+ talloc_free(this);
+ expired_timers++;
+ }
+ }
+}
+
+static void alarm_handler(int signum)
+{
+ fprintf(stderr, "ERROR: We took too long to run the timer test, "
+ "something seems broken, aborting.\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+
+ if (signal(SIGALRM, alarm_handler) == SIG_ERR) {
+ perror("cannot register signal handler");
+ exit(EXIT_FAILURE);
+ }
+
+ while ((c = getopt_long(argc, argv, "s:", NULL, NULL)) != -1) {
+ switch(c) {
+ case 's':
+ timer_nsteps = atoi(optarg);
+ if (timer_nsteps <= 0) {
+ fprintf(stderr, "%s: steps must be > 0\n",
+ argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ default:
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ fprintf(stdout, "Running timer test for %u steps, accepting "
+ "imprecision of %u.%.6u seconds\n",
+ timer_nsteps, TIMER_PRES_SECS, TIMER_PRES_USECS);
+
+ osmo_timer_schedule(&main_timer, 1, 0);
- osmo_timer_schedule(&timer_one, 3, 0);
- osmo_timer_schedule(&timer_two, 5, 0);
- osmo_timer_schedule(&timer_three, 4, 0);
+ /* if the test takes too long, we may consider that the timer scheduler
+ * has hung. We set some maximum wait time which is the double of the
+ * maximum timeout randomly set (10 seconds, worst case) plus the
+ * number of steps (since some of them are reset each step). */
+ alarm(2 * (10 + timer_nsteps));
#ifdef HAVE_SYS_SELECT_H
- while (1) {
- osmo_select_main(0);
- }
+ while (1) {
+ osmo_select_main(0);
+ }
#else
- printf("Select not supported on this platform!\n");
+ fprintf(stdout, "Select not supported on this platform!\n");
#endif
}
diff --git a/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.ok b/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.ok
new file mode 100644
index 0000000..b4e0e11
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/timer/timer_test.ok
@@ -0,0 +1,2 @@
+Running timer test for 5 steps, accepting imprecision of 0.010000 seconds
+test over: added=31 expired=31 too_late=0
diff --git a/Src/osmolib/src/shared/libosmocore/tests/ussd/Makefile.am b/Src/osmolib/src/shared/libosmocore/tests/ussd/Makefile.am
index ef9aa49..de9ff89 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/ussd/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/tests/ussd/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = ussd_test
+EXTRA_DIST = ussd_test.ok
ussd_test_SOURCES = ussd_test.c
ussd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
diff --git a/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.c b/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.c
index 6d2a8c9..55384f1 100644
--- a/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.c
+++ b/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.c
@@ -19,6 +19,8 @@
*
*/
+#include <osmocom/core/application.h>
+#include <osmocom/core/logging.h>
#include <osmocom/gsm/gsm0480.h>
#include <stdio.h>
#include <stdlib.h>
@@ -64,12 +66,16 @@ static int parse_mangle_ussd(const uint8_t *_data, int len)
return rc;
}
+struct log_info info = {};
+
int main(int argc, char **argv)
{
struct ussd_request req;
const int size = sizeof(ussd_request);
int i;
+ osmo_init_logging(&info);
+
gsm0480_decode_ussd_request((struct gsm48_hdr *) ussd_request, size, &req);
printf("Tested if it still works. Text was: %s\n", req.text);
diff --git a/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.ok b/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.ok
new file mode 100644
index 0000000..1b6316e
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/tests/ussd/ussd_test.ok
@@ -0,0 +1,53 @@
+Tested if it still works. Text was: **321#
+Testing parsing a USSD request and truncated versions
+Result for 1 is 28
+Result for 1 is 27
+Result for 1 is 26
+Result for 1 is 25
+Result for 0 is 24
+Result for 0 is 23
+Result for 0 is 22
+Result for 0 is 21
+Result for 0 is 20
+Result for 0 is 19
+Result for 0 is 18
+Result for 0 is 17
+Result for 0 is 16
+Result for 0 is 15
+Result for 0 is 14
+Result for 0 is 13
+Result for 0 is 12
+Result for 0 is 11
+Result for 0 is 10
+Result for 0 is 9
+Result for 0 is 8
+Result for 0 is 7
+Result for 0 is 6
+Result for 0 is 5
+Result for 0 is 4
+Result for 0 is 3
+Mangling the container now
+Result for 0 is 28
+Result for 0 is 27
+Result for 1 is 26
+Result for 1 is 25
+Result for 0 is 24
+Result for 0 is 23
+Result for 0 is 22
+Result for 0 is 21
+Result for 0 is 20
+Result for 0 is 19
+Result for 0 is 18
+Result for 0 is 17
+Result for 0 is 16
+Result for 0 is 15
+Result for 0 is 14
+Result for 0 is 13
+Result for 0 is 12
+Result for 0 is 11
+Result for 0 is 10
+Result for 0 is 9
+Result for 0 is 8
+Result for 0 is 7
+Result for 0 is 6
+Result for 1 is 5
diff --git a/Src/osmolib/src/shared/libosmocore/utils/Makefile.am b/Src/osmolib/src/shared/libosmocore/utils/Makefile.am
index 22903d9..4e7869e 100644
--- a/Src/osmolib/src/shared/libosmocore/utils/Makefile.am
+++ b/Src/osmolib/src/shared/libosmocore/utils/Makefile.am
@@ -1,7 +1,10 @@
if ENABLE_UTILITIES
INCLUDES = $(all_includes) -I$(top_srcdir)/include
-noinst_PROGRAMS = osmo-arfcn
+noinst_PROGRAMS = osmo-arfcn osmo-auc-gen
osmo_arfcn_SOURCES = osmo-arfcn.c
osmo_arfcn_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
+
+osmo_auc_gen_SOURCES = osmo-auc-gen.c
+osmo_auc_gen_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
endif
diff --git a/Src/osmolib/src/shared/libosmocore/utils/gen_website_doc_tree.sh b/Src/osmolib/src/shared/libosmocore/utils/gen_website_doc_tree.sh
index 622db56..622db56 100644..100755
--- a/Src/osmolib/src/shared/libosmocore/utils/gen_website_doc_tree.sh
+++ b/Src/osmolib/src/shared/libosmocore/utils/gen_website_doc_tree.sh
diff --git a/Src/osmolib/src/shared/libosmocore/utils/osmo-auc-gen.c b/Src/osmolib/src/shared/libosmocore/utils/osmo-auc-gen.c
new file mode 100644
index 0000000..62b5128
--- /dev/null
+++ b/Src/osmolib/src/shared/libosmocore/utils/osmo-auc-gen.c
@@ -0,0 +1,183 @@
+/* GSM/GPRS/3G authentication testing tool */
+
+/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <osmocom/crypt/auth.h>
+#include <osmocom/core/utils.h>
+
+static void dump_auth_vec(struct osmo_auth_vector *vec)
+{
+ printf("RAND:\t%s\n", osmo_hexdump(vec->rand, sizeof(vec->rand)));
+
+ if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) {
+ printf("AUTN:\t%s\n", osmo_hexdump(vec->autn, sizeof(vec->autn)));
+ printf("IK:\t%s\n", osmo_hexdump(vec->ik, sizeof(vec->ik)));
+ printf("CK:\t%s\n", osmo_hexdump(vec->ck, sizeof(vec->ck)));
+ printf("RES:\t%s\n", osmo_hexdump(vec->res, vec->res_len));
+ }
+
+ if (vec->auth_types & OSMO_AUTH_TYPE_GSM) {
+ printf("SRES:\t%s\n", osmo_hexdump(vec->sres, sizeof(vec->sres)));
+ printf("Kc:\t%s\n", osmo_hexdump(vec->kc, sizeof(vec->kc)));
+ }
+}
+
+static struct osmo_sub_auth_data test_aud = {
+ .type = OSMO_AUTH_TYPE_NONE,
+ .algo = OSMO_AUTH_ALG_NONE,
+};
+
+int main(int argc, char **argv)
+{
+ struct osmo_auth_vector _vec;
+ struct osmo_auth_vector *vec = &_vec;
+ uint8_t _rand[16];
+ int rc, option_index;
+ int rand_is_set = 0;
+
+ printf("osmo-auc-gen (C) 2011 by Harald Welte\n");
+ printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");
+
+ while (1) {
+ int c;
+ unsigned long ul;
+ static struct option long_options[] = {
+ { "2g", 0, 0, '2' },
+ { "3g", 0, 0, '3' },
+ { "algorithm", 1, 0, 'a' },
+ { "key", 1, 0, 'k' },
+ { "opc", 1, 0, 'o' },
+ { "amf", 1, 0, 'f' },
+ { "sqn", 1, 0, 's' },
+ { "rand", 1, 0, 'r' },
+ { 0, 0, 0, 0 }
+ };
+
+ rc = 0;
+
+ c = getopt_long(argc, argv, "23a:k:o:f:s:r:", long_options,
+ &option_index);
+
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case '2':
+ test_aud.type = OSMO_AUTH_TYPE_GSM;
+ break;
+ case '3':
+ test_aud.type = OSMO_AUTH_TYPE_UMTS;
+ break;
+ case 'a':
+ rc = osmo_auth_alg_parse(optarg);
+ if (rc < 0)
+ break;
+ test_aud.algo = rc;
+ break;
+ case 'k':
+ switch (test_aud.type) {
+ case OSMO_AUTH_TYPE_GSM:
+ rc = osmo_hexparse(optarg, test_aud.u.gsm.ki,
+ sizeof(test_aud.u.gsm.ki));
+ break;
+ case OSMO_AUTH_TYPE_UMTS:
+ rc = osmo_hexparse(optarg, test_aud.u.umts.k,
+ sizeof(test_aud.u.umts.k));
+ break;
+ default:
+ fprintf(stderr, "please specify 2g/3g first!\n");
+ }
+ break;
+ case 'o':
+ if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
+ fprintf(stderr, "Only UMTS has OPC\n");
+ exit(2);
+ }
+ rc = osmo_hexparse(optarg, test_aud.u.umts.opc,
+ sizeof(test_aud.u.umts.opc));
+ break;
+ case 'f':
+ if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
+ fprintf(stderr, "Only UMTS has AMF\n");
+ exit(2);
+ }
+ rc = osmo_hexparse(optarg, test_aud.u.umts.amf,
+ sizeof(test_aud.u.umts.amf));
+ break;
+ case 's':
+ if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
+ fprintf(stderr, "Only UMTS has SQN\n");
+ exit(2);
+ }
+ ul = strtoul(optarg, 0, 10);
+ test_aud.u.umts.sqn = ul;
+ break;
+ case 'r':
+ rc = osmo_hexparse(optarg, _rand, sizeof(_rand));
+ rand_is_set = 1;
+ break;
+ }
+
+ if (rc < 0) {
+ fprintf(stderr, "Error parsing argument of option `%c'\n", c);
+ exit(2);
+ }
+ }
+
+ if (!rand_is_set) {
+ printf("WARNING: We're using really weak random numbers!\n\n");
+ srand(time(NULL));
+ *(uint32_t *)&_rand[0] = rand();
+ *(uint32_t *)(&_rand[4]) = rand();
+ *(uint32_t *)(&_rand[8]) = rand();
+ *(uint32_t *)(&_rand[12]) = rand();
+ }
+
+ memset(vec, 0, sizeof(*vec));
+
+ rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
+ if (rc < 0) {
+ fprintf(stderr, "error generating auth vector\n");
+ exit(1);
+ }
+
+ dump_auth_vec(vec);
+#if 0
+ const uint8_t auts[14] = { 0x87, 0x11, 0xa0, 0xec, 0x9e, 0x16, 0x37, 0xdf,
+ 0x17, 0xf8, 0x0b, 0x38, 0x4e, 0xe4 };
+
+ rc = osmo_auth_gen_vec_auts(vec, &test_aud, auts, _rand, _rand);
+ if (rc < 0) {
+ printf("AUTS failed\n");
+ } else {
+ printf("AUTS success: SEQ.MS = %lu\n", test_aud.u.umts.sqn);
+ }
+#endif
+ exit(0);
+
+}
diff --git a/Src/osmolib/src/shared/update-libosmocore.sh b/Src/osmolib/src/shared/update-libosmocore.sh
index 69dfbe1..69dfbe1 100644..100755
--- a/Src/osmolib/src/shared/update-libosmocore.sh
+++ b/Src/osmolib/src/shared/update-libosmocore.sh
diff --git a/Src/osmolib/src/target/firmware/Makefile b/Src/osmolib/src/target/firmware/Makefile
index 4ccd395..3af2f67 100644
--- a/Src/osmolib/src/target/firmware/Makefile
+++ b/Src/osmolib/src/target/firmware/Makefile
@@ -4,8 +4,19 @@
BOARDS?=compal_e88 compal_e86 compal_e99 se_j100 gta0x pirelli_dpl10
# List of all applications (meant to be overridden on command line)
-APPLICATIONS?=hello_world compal_dsp_dump layer1 loader simtest chainload
+APPLICATIONS?=hello_world compal_dsp_dump layer1 loader chainload rssi
+# Framebuffer support, board specific drivers
+#
+
+FB_OBJS=fb/framebuffer.o fb/font.o fb/helvR08.o fb/helvB14.o fb/c64.o
+
+FB_e88_OBJS=$(FB_OBJS) fb/fb_bw8.o fb/fb_st7558.o
+FB_e99_OBJS=$(FB_OBJS) fb/fb_rgb332.o fb/fb_ssd1783.o
+FB_e86_OBJS=$(FB_OBJS) fb/fb_rgb332.o fb/fb_td014.o
+FB_j100_OBJS=$(FB_OBJS) fb/fb_rgb332.o fb/fb_ssd1963.o
+FB_dpl10_OBJS=$(FB_OBJS) fb/fb_rgb332.o fb/fb_s6b33b1x.o
+FB_dummy_OBJS=$(FB_OBJS) fb/fb_dummy.o
# TI Calypso
@@ -13,12 +24,12 @@ calypso_COMMON_OBJS=board/common/calypso_uart.o board/common/calypso_pwl.o
# OpenMoko GTA0x
-gta0x_OBJS=$(calypso_COMMON_OBJS) board/gta0x/rffe_gta0x_triband.o board/gta0x/init.o board/gta0x/rf_power.o
+gta0x_OBJS=$(calypso_COMMON_OBJS) board/gta0x/rffe_gta0x_triband.o board/gta0x/init.o board/gta0x/rf_power.o $(FB_dummy_OBJS)
gta0x_ENVIRONMENTS=highram
# Pirelli DP-L10
-pirelli_dpl10_OBJS=$(calypso_COMMON_OBJS) board/pirelli_dpl10/rffe_dpl10_triband.o board/pirelli_dpl10/init.o board/pirelli_dpl10/rf_power.o
+pirelli_dpl10_OBJS=$(calypso_COMMON_OBJS) board/pirelli_dpl10/rffe_dpl10_triband.o board/pirelli_dpl10/init.o board/pirelli_dpl10/rf_power.o $(FB_dpl10_OBJS)
pirelli_dpl10_ENVIRONMENTS=highram
# Compal Generic
@@ -34,7 +45,7 @@ highram_OBJS=board/compal/start.ram.o board/compal/exceptions_redirected.o board
# Compal E88
-compal_e88_OBJS=$(compal_COMMON_OBJS) board/compal_e88/init.o
+compal_e88_OBJS=$(compal_COMMON_OBJS) board/compal_e88/init.o $(FB_e88_OBJS)
compal_e88_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS) e88loader e88flash
e88loader_LDS=board/compal_e88/loader.lds
@@ -45,12 +56,12 @@ e88flash_OBJS=board/compal/start.rom.o board/compal/header.o board/compal/except
# Compal E86 (has a different RFFE configuration)
-compal_e86_OBJS=$(calypso_COMMON_OBJS) board/compal_e86/rffe_dualband_e86.o board/compal/rf_power.o board/compal_e86/init.o
+compal_e86_OBJS=$(calypso_COMMON_OBJS) board/compal_e86/rffe_dualband_e86.o board/compal/rf_power.o board/compal_e86/init.o $(FB_e86_OBJS)
compal_e86_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
# Compal E99
-compal_e99_OBJS=$(compal_COMMON_OBJS) board/compal_e99/init.o
+compal_e99_OBJS=$(compal_COMMON_OBJS) board/compal_e99/init.o $(FB_e99_OBJS)
compal_e99_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
e99loader_LDS=board/compal_e99/loader.lds
@@ -59,7 +70,7 @@ e99flash_LDS=board/compal_e99/flash.lds
# Sony Ericsson J100 (made by Compal)
-se_j100_OBJS=$(compal_COMMON_OBJS) board/se_j100/init.o
+se_j100_OBJS=$(compal_COMMON_OBJS) board/se_j100/init.o $(FB_j100_OBJS)
se_j100_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
# Global include path
@@ -67,12 +78,11 @@ INCLUDES=-Iinclude/ -I../../../include -I../../shared/libosmocore/include
# Various objects that are currently linked into all applications
FLASH_OBJS=flash/cfi_flash.o
-DISPLAY_OBJS=display/font_r8x8.o display/font_r8x8_horiz.o display/st7558.o display/td014.o display/ssd1783.o display/ssd1963.o display/display.o
ABB_OBJS=abb/twl3025.o
RF_OBJS=rf/trf6151.o
# Objects that go in all applications
-ANY_APP_OBJS+=$(ABB_OBJS) $(RF_OBJS) $(DISPLAY_OBJS) $(FLASH_OBJS)
+ANY_APP_OBJS+=$(ABB_OBJS) $(RF_OBJS) $(FLASH_OBJS)
ANY_APP_LIBS+=calypso/libcalypso.a layer1/liblayer1.a lib/libmini.a comm/libcomm.a ../../shared/libosmocore/build-target/src/.libs/libosmocore.a ../../shared/libosmocore/build-target/src/gsm/.libs/libosmogsm.a
# Libraries are defined in subdirectories
diff --git a/Src/osmolib/src/target/firmware/abb/twl3025.c b/Src/osmolib/src/target/firmware/abb/twl3025.c
index 564c34b..e4fcf4f 100644
--- a/Src/osmolib/src/target/firmware/abb/twl3025.c
+++ b/Src/osmolib/src/target/firmware/abb/twl3025.c
@@ -31,6 +31,7 @@
#include <calypso/tsp.h>
#include <calypso/tpu.h>
#include <abb/twl3025.h>
+#include <asm/system.h>
/* TWL3025 */
#define REG_PAGE(n) (n >> 7)
@@ -105,13 +106,6 @@ static void twl3025_irq(enum irq_nr nr)
case IRQ_EXTERNAL: // charger in/out, pwrbtn, adc done
src = twl3025_reg_read(ITSTATREG);
// printd("itstatreg 0x%02x\n", src);
- if (src & 0x04) {
- /* poll PWON status and power off the phone when the
- * powerbutton has been released (otherwise it will
- * poweron immediately again) */
- while (!(twl3025_reg_read(VRPCSTS) & 0x10)) { };
- twl3025_power_off();
- }
if (src & 0x08)
handle_charger();
if (src & 0x20)
@@ -193,6 +187,17 @@ static void twl3025_wait_ibic_access(void)
void twl3025_power_off(void)
{
+ unsigned long flags;
+
+ /* turn off all IRQs, since received frames cannot be
+ * handled form here. (otherwise the message allocation
+ * runs out of memory) */
+ local_firq_save(flags);
+
+ /* poll PWON status and power off the phone when the
+ * powerbutton has been released (otherwise it will
+ * poweron immediately again) */
+ while (!(twl3025_reg_read(VRPCSTS) & 0x10)) { };
twl3025_reg_write(VRPCDEV, 0x01);
}
diff --git a/Src/osmolib/src/target/firmware/apps/chainload/main.c b/Src/osmolib/src/target/firmware/apps/chainload/main.c
index 5121837..9dfa217 100644
--- a/Src/osmolib/src/target/firmware/apps/chainload/main.c
+++ b/Src/osmolib/src/target/firmware/apps/chainload/main.c
@@ -29,6 +29,7 @@
#include <delay.h>
#include <calypso/clock.h>
+#include <calypso/timer.h>
/* Main Program */
diff --git a/Src/osmolib/src/target/firmware/apps/compal_dsp_dump/main.c b/Src/osmolib/src/target/firmware/apps/compal_dsp_dump/main.c
index c823d0a..f148d50 100644
--- a/Src/osmolib/src/target/firmware/apps/compal_dsp_dump/main.c
+++ b/Src/osmolib/src/target/firmware/apps/compal_dsp_dump/main.c
@@ -37,6 +37,7 @@
#include <calypso/irq.h>
#include <calypso/misc.h>
#include <comm/timer.h>
+#include <fb/framebuffer.h>
/* Main Program */
const char *hr = "======================================================================\n";
@@ -52,11 +53,33 @@ int main(void)
dump_dev_id();
puts(hr);
+ fb_clear();
+
+ fb_setfg(FB_COLOR_BLACK);
+ fb_setbg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_HELVB14);
+
+ fb_gotoxy(2,20);
+ fb_putstr("DSP Dump",framebuffer->width-4);
+
+ fb_setfg(FB_COLOR_RED);
+ fb_setbg(FB_COLOR_BLUE);
+
+ fb_gotoxy(2,25);
+ fb_boxto(framebuffer->width-3,38);
+
+ fb_setfg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(8,33);
+ fb_putstr("osmocom-bb",framebuffer->width-4);
+
+ fb_flush();
+
/* Dump DSP content */
dsp_dump();
while (1) {
- update_timers();
+ osmo_timers_update();
}
}
diff --git a/Src/osmolib/src/target/firmware/apps/hello_world/main.c b/Src/osmolib/src/target/firmware/apps/hello_world/main.c
index 5e3ed85..cdf4dae 100644
--- a/Src/osmolib/src/target/firmware/apps/hello_world/main.c
+++ b/Src/osmolib/src/target/firmware/apps/hello_world/main.c
@@ -31,7 +31,6 @@
#include <keypad.h>
#include <board.h>
#include <abb/twl3025.h>
-#include <display.h>
#include <rf/trf6151.h>
#include <calypso/clock.h>
#include <calypso/tpu.h>
@@ -41,6 +40,7 @@
#include <calypso/misc.h>
#include <comm/sercomm.h>
#include <comm/timer.h>
+#include <fb/framebuffer.h>
/* Main Program */
const char *hr = "======================================================================\n";
@@ -55,7 +55,6 @@ static void console_rx_cb(uint8_t dlci, struct msgb *msg)
}
printf("Message on console DLCI: '%s'\n", msg->data);
- display_puts((char *) msg->data);
msgb_free(msg);
}
@@ -89,6 +88,30 @@ int main(void)
calypso_clk_dump();
puts(hr);
+ fb_clear();
+
+ fb_setfg(FB_COLOR_BLACK);
+ fb_setbg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_HELVB14);
+
+ fb_gotoxy(2,20);
+ fb_putstr("Hello World!",framebuffer->width-4);
+
+ fb_setfg(FB_COLOR_RED);
+ fb_setbg(FB_COLOR_BLUE);
+
+ fb_gotoxy(2,25);
+ fb_boxto(framebuffer->width-3,38);
+
+ fb_setfg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(8,33);
+ fb_putstr("osmocom-bb",framebuffer->width-4);
+
+ fb_flush();
+
+
+
/* Dump all memory */
//dump_mem();
#if 0
@@ -97,16 +120,13 @@ int main(void)
puts(hr);
#endif
- display_set_attr(DISP_ATTR_INVERT);
- display_puts("Hello World");
-
sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
sercomm_register_rx_cb(SC_DLCI_L1A_L23, l1a_l23_rx_cb);
/* beyond this point we only react to interrupts */
puts("entering interrupt loop\n");
while (1) {
- update_timers();
+ osmo_timers_update();
}
twl3025_power_off();
@@ -132,16 +152,13 @@ void key_handler(enum key_codes code, enum key_states state)
case KEY_7:
case KEY_8:
case KEY_9:
- sprintf(test, "%d", code - KEY_0);
- display_puts(test);
+ // used to be display_puts...
break;
case KEY_STAR:
- sprintf(test, "*", 0);
- display_puts(test);
+ // used to be display puts...
break;
case KEY_HASH:
- sprintf(test, "#", 0);
- display_puts(test);
+ // used to be display puts...
break;
default:
break;
diff --git a/Src/osmolib/src/target/firmware/apps/layer1/main.c b/Src/osmolib/src/target/firmware/apps/layer1/main.c
index 8eaf4a6..a8d4f5d 100644
--- a/Src/osmolib/src/target/firmware/apps/layer1/main.c
+++ b/Src/osmolib/src/target/firmware/apps/layer1/main.c
@@ -25,13 +25,13 @@
#include <debug.h>
#include <memory.h>
+#include <string.h>
#include <delay.h>
#include <rffe.h>
#include <keypad.h>
#include <board.h>
#include <abb/twl3025.h>
-#include <display.h>
#include <rf/trf6151.h>
#include <comm/sercomm.h>
@@ -42,9 +42,14 @@
#include <calypso/tsp.h>
#include <calypso/irq.h>
#include <calypso/misc.h>
+#include <calypso/sim.h>
#include <layer1/sync.h>
+#include <layer1/async.h>
#include <layer1/tpu_window.h>
+#include <layer1/l23_api.h>
+
+#include <fb/framebuffer.h>
const char *hr = "======================================================================\n";
@@ -54,6 +59,9 @@ static void key_handler(enum key_codes code, enum key_states state);
int main(void)
{
+ uint8_t atr[20];
+ uint8_t atrLength = 0;
+
board_init();
puts("\n\nOSMOCOM Layer 1 (revision " GIT_REVISION ")\n");
@@ -69,17 +77,44 @@ int main(void)
calypso_clk_dump();
puts(hr);
- display_puts("layer1.bin");
+ fb_clear();
- layer1_init();
+ fb_setfg(FB_COLOR_BLACK);
+ fb_setbg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_HELVB14);
+
+ fb_gotoxy(2,20);
+ fb_putstr("Layer 1",framebuffer->width-4);
+
+ fb_setfg(FB_COLOR_RED);
+ fb_setbg(FB_COLOR_BLUE);
+
+ fb_gotoxy(2,25);
+ fb_boxto(framebuffer->width-3,38);
- display_unset_attr(DISP_ATTR_INVERT);
+ fb_setfg(FB_COLOR_WHITE);
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(8,33);
+ fb_putstr("osmocom-bb",framebuffer->width-4);
+
+ fb_flush();
+
+ /* initialize SIM */
+ calypso_sim_init();
+
+ puts("Power up simcard:\n");
+ memset(atr,0,sizeof(atr));
+ atrLength = calypso_sim_powerup(atr);
+
+ layer1_init();
tpu_frame_irq_en(1, 1);
while (1) {
l1a_compl_execute();
- update_timers();
+ osmo_timers_update();
+ sim_handler();
+ l1a_l23_handler();
}
/* NOT REACHED */
@@ -130,6 +165,9 @@ static void key_handler(enum key_codes code, enum key_states state)
default:
break;
}
+ /* power down SIM, TODO: this will happen with every key pressed,
+ put it somewhere else ! */
+ calypso_sim_powerdown();
}
diff --git a/Src/osmolib/src/target/firmware/apps/loader/main.c b/Src/osmolib/src/target/firmware/apps/loader/main.c
index 2ff6f9c..c55c56c 100644
--- a/Src/osmolib/src/target/firmware/apps/loader/main.c
+++ b/Src/osmolib/src/target/firmware/apps/loader/main.c
@@ -45,6 +45,7 @@
#include <calypso/tsp.h>
#include <calypso/irq.h>
#include <calypso/misc.h>
+#include <calypso/backlight.h>
#include <uart.h>
#include <calypso/timer.h>
diff --git a/Src/osmolib/src/target/firmware/apps/rssi/main.c b/Src/osmolib/src/target/firmware/apps/rssi/main.c
new file mode 100644
index 0000000..a189740
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/apps/rssi/main.c
@@ -0,0 +1,1544 @@
+/* Cell Monitor of Free Software for Calypso Phone */
+
+/* (C) 2012 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <debug.h>
+#include <memory.h>
+#include <delay.h>
+#include <byteorder.h>
+#include <rffe.h>
+#include <keypad.h>
+#include <board.h>
+#include <abb/twl3025.h>
+#include <rf/trf6151.h>
+#include <calypso/clock.h>
+#include <calypso/tpu.h>
+#include <calypso/tsp.h>
+#include <calypso/dsp.h>
+#include <calypso/irq.h>
+#include <calypso/misc.h>
+#include <calypso/buzzer.h>
+#include <comm/sercomm.h>
+#include <comm/timer.h>
+#include <fb/framebuffer.h>
+#include <layer1/sync.h>
+#include <layer1/async.h>
+#include <layer1/l23_api.h>
+#include <osmocom/gsm/rsl.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48_ie.h>
+
+enum key_codes key_code = KEY_INV;
+int key_pressed = 0;
+enum key_codes key_pressed_code;
+unsigned long key_pressed_when;
+unsigned int key_pressed_delay;
+
+enum mode {
+ MODE_MAIN,
+ MODE_SPECTRUM,
+ MODE_ARFCN,
+ MODE_SYNC,
+ MODE_RACH,
+} mode = MODE_MAIN;
+enum mode last_mode; /* where to return after entering ARFCN */
+
+static uint16_t arfcn = 0, ul_arfcn;
+int pcs = 0;
+int uplink = 0;
+int max = 0;
+uint8_t power, max_power;
+char input[5];
+int cursor;
+
+char *sync_result = NULL;
+char *sync_msg = "";
+
+static struct band {
+ int min, max, prev, next, freq_ul, freq_dl;
+} bands[] = {
+ { 128, 251, 124, 512, 8242, 8692 }, /* GSM 850 */
+ { 955, 124, 885, 128, 8762, 9212 }, /* P,E,R GSM */
+ { 512, 885, 251, 955, 17102, 18052 }, /* DCS 1800 */
+ { 0, 0, 0, 0, 0, 0},
+};
+
+struct band *band;
+
+#define PCS_MIN 512
+#define PCS_MAX 810
+#define DCS_MIN 512
+#define DCS_MAX 885
+#define PCS_UL 18502
+#define PCS_DL 19302
+
+enum pm_mode {
+ PM_IDLE,
+ PM_SENT,
+ PM_RANGE_SENT,
+ PM_RANGE_RESULT,
+ PM_RESULT,
+} pm_mode = PM_IDLE;
+
+#define NUM_PM_DL 2
+#define NUM_PM_UL 10
+int pm_meas[NUM_PM_UL];
+int pm_count = 0;
+int pm_max = 2;
+uint8_t pm_spectrum[1024];
+int pm_scale = 1; /* scale measured power level */
+
+#define TONE_JIFFIES ((HZ < 25) ? 1 : HZ / 25)
+int tone = 0;
+unsigned long tone_time;
+int tone_on = 0;
+
+uint8_t bsic;
+uint8_t ul_levels[8], ul_max[8]; /* 8 uplink levels */
+uint8_t si_1[23];
+uint8_t si_2[23];
+uint8_t si_2bis[23];
+uint8_t si_2ter[23];
+uint8_t si_3[23];
+uint8_t si_4[23];
+uint16_t si_new = 0, ul_new;
+uint16_t mcc, mnc, lac, cell_id;
+int ccch_conf;
+int nb_num;
+struct gsm_sysinfo_freq freq[1024];
+#define NEIGH_LINES ((framebuffer->height - 25) / 8)
+
+#define FREQ_TYPE_SERV 0x01 /* frequency of the serving cell */
+#define FREQ_TYPE_NCELL 0x1c /* frequency of the neighbor cell */
+#define FREQ_TYPE_NCELL_2 0x04 /* sub channel of SI 2 */
+#define FREQ_TYPE_NCELL_2bis 0x08 /* sub channel of SI 2bis */
+#define FREQ_TYPE_NCELL_2ter 0x10 /* sub channel of SI 2ter */
+
+int rach = 0;
+struct gsm48_req_ref rach_ref;
+uint8_t rach_ra;
+unsigned long rach_when;
+uint8_t ta;
+
+enum assign {
+ ASSIGN_NONE,
+ ASSIGN_NO_TX,
+ ASSIGN_RESULT,
+ ASSIGN_REJECT,
+ ASSIGN_TIMEOUT,
+} assign;
+
+/* UI */
+
+static void print_display(char *text, int *y, int c)
+{
+ /* skip lines, given by cursor */
+ (*y)++;
+ if (c >= (*y))
+ return;
+ /* skip, if end of display area is reached */
+ if ((*y) - c > NEIGH_LINES)
+ return;
+
+ fb_gotoxy(0, 20 + (((*y) - c - 1) << 3));
+ fb_putstr(text, framebuffer->width);
+}
+
+static void refresh_display(void)
+{
+ char text[16];
+
+ fb_clear();
+
+ /* header */
+ fb_setbg(FB_COLOR_WHITE);
+ if (mode != MODE_SPECTRUM && !(mode == MODE_SYNC && cursor < 0)) {
+ fb_setfg(FB_COLOR_BLUE);
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(0, 7);
+ fb_putstr("Osmocom Monitor Tool", -1);
+ fb_gotoxy(0, 10);
+ fb_setfg(FB_COLOR_GREEN);
+ fb_boxto(framebuffer->width - 1, 10);
+ }
+ fb_setfg(FB_COLOR_BLACK);
+ fb_setfont(FB_FONT_C64);
+
+ /* RACH */
+ if (mode == MODE_RACH) {
+ unsigned long elapsed = jiffies - rach_when;
+
+ fb_gotoxy(0,28);
+ switch (assign) {
+ case ASSIGN_NONE:
+ fb_putstr("Rach sent...", -1);
+ break;
+ case ASSIGN_RESULT:
+ sprintf(text, "TA = %d", ta);
+ fb_putstr(text, -1);
+ fb_gotoxy(0,36);
+ sprintf(text, "(%dm)", ta * 554);
+ fb_putstr(text, -1);
+ break;
+ case ASSIGN_REJECT:
+ fb_putstr("Rejected!", -1);
+ break;
+ case ASSIGN_NO_TX:
+ fb_putstr("TX disabled", -1);
+ break;
+ case ASSIGN_TIMEOUT:
+ fb_putstr("Timeout", -1);
+ break;
+ }
+ switch (assign) {
+ case ASSIGN_RESULT:
+ case ASSIGN_REJECT:
+ fb_gotoxy(0,44);
+ sprintf(text, "Delay:%ldms", elapsed * 1000 / HZ);
+ fb_putstr(text, -1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* SYNC / UL levels */
+ if (mode == MODE_SYNC && cursor < 0) {
+ int i, tn, l;
+ int offset = (framebuffer->width - 96) >> 1;
+ int height = framebuffer->height - 25;
+
+ fb_setfont(FB_FONT_HELVR08);
+ for (i = 0; i < 8; i++) {
+ if (uplink)
+ tn = (i + 3) & 7; /* UL is shifted by 3 */
+ else
+ tn = i;
+ fb_setbg(FB_COLOR_WHITE);
+ fb_gotoxy(offset + 12 * i, 7);
+ l = (max) ? ul_max[tn] : ul_levels[tn];
+ l = 110 - l;
+ if (l >= 100)
+ l -= 100;
+ sprintf(text, "%02d", l);
+ fb_putstr(text, framebuffer->width);
+ fb_setbg(FB_COLOR_BLACK);
+ fb_gotoxy(offset + 3 + 12 * i, height + 10);
+ fb_boxto(offset + 3 + 12 * i + 5, height + 10 - ul_levels[tn] * height / 64);
+ if (max) {
+ fb_gotoxy(offset + 3 + 12 * i, height + 10 - ul_max[tn] * height / 64);
+ fb_boxto(offset + 3 + 12 * i + 5, height + 10 - ul_max[tn] * height / 64);
+ }
+ }
+ fb_setbg(FB_COLOR_TRANSP);
+ if (max) {
+ fb_setfg(FB_COLOR_RED);
+ fb_gotoxy(framebuffer->width - 16, 15);
+ fb_putstr("max", framebuffer->width);
+ }
+ fb_setfont(FB_FONT_C64);
+ fb_setfg(FB_COLOR_BLUE);
+ fb_gotoxy(0, 16);
+ if (pcs && ul_arfcn >= PCS_MIN && ul_arfcn <= PCS_MAX)
+ sprintf(text, "%4dP", ul_arfcn);
+ else if (ul_arfcn >= DCS_MIN && ul_arfcn <= DCS_MAX)
+ sprintf(text, "%4dD", ul_arfcn);
+ else
+ sprintf(text, "%4d ", ul_arfcn);
+ fb_putstr(text, framebuffer->width);
+ fb_setbg(FB_COLOR_WHITE);
+ fb_setfg(FB_COLOR_BLACK);
+ }
+
+ /* SYNC / SI */
+ if (mode == MODE_SYNC && cursor == 0) {
+ fb_gotoxy(0, 20);
+ if (sync_msg[0] == 'o')
+ sprintf(text, "BSIC%d/%d %4d", bsic >> 3, bsic & 7,
+ power - 110);
+ else
+ sprintf(text, "Sync %s", sync_msg);
+ fb_putstr(text, -1);
+
+ fb_gotoxy(0,28);
+ text[0] = si_1[2] ? '1' : '-';
+ text[1] = ' ';
+ text[2] = si_2[2] ? '2' : '-';
+ text[3] = ' ';
+ text[4] = si_2bis[2] ? '2' : '-';
+ text[5] = si_2bis[2] ? 'b' : ' ';
+ text[6] = si_2ter[2] ? '2' : '-';
+ text[7] = si_2ter[2] ? 't' : ' ';
+ text[8] = ' ';
+ text[9] = si_3[2] ? '3' : '-';
+ text[10] = ' ';
+ text[11] = si_4[2] ? '4' : '-';
+ text[12] = '\0';
+ fb_putstr(text, -1);
+
+ fb_gotoxy(0, 36);
+ fb_putstr("MCC MNC LAC ", -1);
+ fb_gotoxy(0, 44);
+ if (mcc) {
+ if ((mnc & 0x00f) == 0x00f)
+ sprintf(text, "%3x %02x %04x", mcc, mnc >> 4, lac);
+ else
+ sprintf(text, "%3x %03x %04x", mcc, mnc, lac);
+ fb_putstr(text, -1);
+ } else
+ fb_putstr("--- --- ----", -1);
+ fb_gotoxy(0, 52);
+ if (si_3[2]) {
+ sprintf(text, "cell id:%04x", cell_id);
+ fb_putstr(text, -1);
+ } else
+ fb_putstr("cell id:----", -1);
+ }
+
+ /* SYNC / neighbour cells */
+ if (mode == MODE_SYNC && cursor > 0) {
+ int i, y = 0;
+
+ text[0] = '\0';
+ for (i = 0; i < 1024; i++) {
+ if (freq[i].mask & FREQ_TYPE_SERV) {
+ if (!text[0])
+ sprintf(text, "S: %4d", i);
+ else {
+ sprintf(text + 7, " %4d", i);
+ print_display(text, &y, cursor - 1);
+ text[0] = '\0';
+ }
+ }
+ }
+ if (text[0])
+ print_display(text, &y, cursor - 1);
+ text[0] = '\0';
+ for (i = 0; i < 1024; i++) {
+ if (freq[i].mask & FREQ_TYPE_NCELL) {
+ if (!text[0])
+ sprintf(text, "N: %4d", i);
+ else {
+ sprintf(text + 7, " %4d", i);
+ print_display(text, &y, cursor - 1);
+ text[0] = '\0';
+ }
+ }
+ }
+ if (text[0])
+ print_display(text, &y, cursor - 1);
+ nb_num = y;
+ }
+
+ /* ARFCN */
+ if (mode == MODE_MAIN || mode == MODE_ARFCN) {
+ fb_gotoxy(0, 20);
+ if (mode == MODE_ARFCN)
+ sprintf(text, "ARFCN %s", input);
+ else if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX)
+ sprintf(text, "ARFCN %dPCS", arfcn);
+ else if (arfcn >= DCS_MIN && arfcn <= DCS_MAX)
+ sprintf(text, "ARFCN %dDCS", arfcn);
+ else
+ sprintf(text, "ARFCN %d", arfcn);
+ fb_putstr(text,framebuffer->width);
+ }
+
+ /* cursor */
+ if (mode == MODE_ARFCN) {
+ fb_setfg(FB_COLOR_WHITE);
+ fb_setbg(FB_COLOR_BLUE);
+ fb_putstr(" ", framebuffer->width);
+ fb_setfg(FB_COLOR_BLACK);
+ fb_setbg(FB_COLOR_WHITE);
+ }
+
+ /* Frequency / power */
+ if (mode == MODE_MAIN) {
+ int f;
+
+ if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX) {
+ if (uplink)
+ f = PCS_UL;
+ else
+ f = PCS_DL;
+ } else if (uplink)
+ f = band->freq_ul;
+ else
+ f = band->freq_dl;
+ f += ((arfcn - band->min) & 1023) << 1;
+
+ fb_gotoxy(0, 30);
+ sprintf(text, "Freq. %d.%d", f / 10, f % 10);
+ fb_putstr(text,framebuffer->width);
+
+ fb_gotoxy(0, 40);
+ sprintf(text, "Power %d", ((max) ? max_power : power) - 110);
+ fb_putstr(text, framebuffer->width);
+ if (max) {
+ fb_setfont(FB_FONT_HELVR08);
+ fb_setfg(FB_COLOR_RED);
+ fb_gotoxy(framebuffer->width - 16, 39);
+ fb_putstr("max", framebuffer->width);
+ fb_setfont(FB_FONT_C64);
+ fb_setfg(FB_COLOR_BLACK);
+ }
+ fb_setbg(FB_COLOR_BLACK);
+ fb_gotoxy(0, 45);
+ fb_boxto(framebuffer->width * power / 64, 50);
+ if (max) {
+ fb_gotoxy(framebuffer->width * max_power / 64 ,45);
+ fb_boxto(framebuffer->width * max_power / 64, 50);
+ }
+ fb_setbg(FB_COLOR_WHITE);
+ }
+
+ /* spectrum */
+ if (mode == MODE_SPECTRUM) {
+ int i;
+ uint16_t a, e, p;
+ int height = framebuffer->height - 25;
+
+ fb_gotoxy(0, 8);
+ if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX)
+ sprintf(text, "%4dP", arfcn);
+ else if (arfcn >= DCS_MIN && arfcn <= DCS_MAX)
+ sprintf(text, "%4dD", arfcn);
+ else
+ sprintf(text, "%4d ", arfcn);
+ sprintf(text + 5, " %4d", pm_spectrum[arfcn & 1023] - 110);
+ fb_putstr(text, -1);
+ fb_setfg(FB_COLOR_RED);
+ if (max) {
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(framebuffer->width - 16,15);
+ fb_putstr("max", framebuffer->width);
+ fb_setfont(FB_FONT_C64);
+ }
+ if (pm_scale != 1) {
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(1, 15);
+ sprintf(text, "x%d", pm_scale);
+ fb_putstr(text, framebuffer->width);
+ fb_setfont(FB_FONT_C64);
+ }
+ fb_setfg(FB_COLOR_BLACK);
+ if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX) {
+ a = PCS_MIN;
+ e = PCS_MAX;
+ } else {
+ a = band->min;
+ e = band->max;
+ }
+ for (i = 0; i < framebuffer->width; i++) {
+ p = (arfcn + i - (framebuffer->width >> 1)) & 1023;
+ if ((((p - a) & 1023) & 512))
+ continue;
+ if ((((e - p) & 1023) & 512))
+ continue;
+ p = (pm_spectrum[p] * pm_scale * height / 64);
+ if (p > height)
+ p = height;
+ if (i == (framebuffer->width >> 1))
+ fb_setfg(FB_COLOR_RED);
+ fb_gotoxy(i, height + 10 - p);
+ fb_boxto(i, height + 10);
+ if (i == (framebuffer->width >> 1))
+ fb_setfg(FB_COLOR_BLACK);
+ }
+ i = framebuffer->width >> 1;
+ fb_gotoxy(i, 0);
+ fb_boxto(i, 4);
+ fb_gotoxy(i, height + 10);
+ fb_boxto(i, height + 14);
+ }
+
+ /* footer */
+ fb_setfg(FB_COLOR_GREEN);
+ fb_gotoxy(0, framebuffer->height - 10);
+ fb_boxto(framebuffer->width-1, framebuffer->height - 10);
+ fb_gotoxy(0, framebuffer->height - 1);
+ fb_setfg(FB_COLOR_RED);
+ if (mode == MODE_ARFCN)
+ sprintf(text, "%s %s", (cursor) ? "del " : "back",
+ (cursor) ? "enter" : " ");
+ else if (mode == MODE_SYNC && cursor < 0)
+ sprintf(text, "%s %s", "back",
+ (uplink) ? "UL" : "DL");
+ else if (mode == MODE_SYNC || mode == MODE_RACH)
+ sprintf(text, "%s ", "back");
+ else
+ sprintf(text, "%s %s", (pcs) ? "PCS" : "DCS",
+ (uplink) ? "UL" : "DL");
+ fb_putstr(text, -1);
+ fb_setfg(FB_COLOR_BLACK);
+ fb_setfont(FB_FONT_HELVR08);
+ fb_gotoxy(0, framebuffer->height - 2);
+ sprintf(text, "%d", tone / 25);
+ fb_putstr(text, -1);
+
+ fb_flush();
+}
+
+static void exit_arfcn(void)
+{
+ mode = last_mode;
+ refresh_display();
+}
+
+static void enter_arfcn(enum key_codes code)
+{
+ /* enter mode */
+ if (mode != MODE_ARFCN) {
+ last_mode = mode;
+ mode = MODE_ARFCN;
+ input[0] = code - KEY_0 + '0';
+ input[1] = '\0';
+ cursor = 1;
+ refresh_display();
+ return;
+ }
+
+ if (code == KEY_LEFT_SB) {
+ /* back */
+ if (cursor == 0) {
+ exit_arfcn();
+ return;
+ }
+ /* delete */
+ cursor--;
+ input[cursor] = '\0';
+ refresh_display();
+ return;
+ }
+
+ if (code == KEY_RIGHT_SB) {
+ int check = 0;
+ int i;
+ struct band *temp = NULL;
+
+ /* nothing entered */
+ if (cursor == 0) {
+ return;
+ }
+ for (i = 0; i < cursor; i++)
+ check = (check << 3) + (check << 1) + input[i] - '0';
+
+ /* check */
+ for (i = 0; bands[i].max; i++) {
+ temp = &bands[i];
+ if (temp->min < temp->max) {
+ if (check >= temp->min && check <= temp->max)
+ break;
+ } else {
+ if (check >= temp->min || check <= temp->max)
+ break;
+ }
+ }
+ if (!bands[i].max)
+ return;
+ if (check > 1023)
+ return;
+ arfcn = check;
+ band = temp;
+ mode = last_mode;
+ refresh_display();
+ return;
+ }
+
+ if (cursor == 4)
+ return;
+
+ input[cursor] = code - KEY_0 + '0';
+ cursor++;
+ input[cursor] = '\0';
+ refresh_display();
+}
+
+static int inc_dec_arfcn(int inc)
+{
+ int i;
+
+ /* select current band */
+ for (i = 0; bands[i].max; i++) {
+ band = &bands[i];
+ if (band->min < band->max) {
+ if (arfcn >= band->min && arfcn <= band->max)
+ break;
+ } else {
+ if (arfcn >= band->min || arfcn <= band->max)
+ break;
+ }
+ }
+ if (!bands[i].max)
+ return -EINVAL;
+
+ if (inc) {
+ if (arfcn == band->max)
+ arfcn = band->next;
+ else if (arfcn == 1023)
+ arfcn = 0;
+ else
+ arfcn++;
+ } else {
+ if (arfcn == band->min)
+ arfcn = band->prev;
+ else if (arfcn == 0)
+ arfcn = 1023;
+ else
+ arfcn--;
+ }
+ /* select next band */
+ for (i = 0; bands[i].max; i++) {
+ band = &bands[i];
+ if (band->min < band->max) {
+ if (arfcn >= band->min && arfcn <= band->max)
+ break;
+ } else {
+ if (arfcn >= band->min || arfcn <= band->max)
+ break;
+ }
+ }
+ if (!bands[i].max)
+ return -EINVAL;
+
+ refresh_display();
+
+ return 0;
+}
+
+static void request_ul_levels(uint16_t a);
+
+static int inc_dec_ul_arfcn(int inc)
+{
+ uint16_t a;
+
+ /* loop until we hit a serving cell or our current bcch arfcn */
+ if (inc) {
+ for (a = (ul_arfcn + 1) & 1023; a != (arfcn & 1023);
+ a = (a + 1) & 1023) {
+ if ((freq[a].mask & FREQ_TYPE_SERV))
+ break;
+ }
+ } else {
+ for (a = (ul_arfcn - 1) & 1023; a != (arfcn & 1023);
+ a = (a - 1) & 1023) {
+ if ((freq[a].mask & FREQ_TYPE_SERV))
+ break;
+ }
+ }
+ ul_arfcn = a;
+
+ refresh_display();
+
+ request_ul_levels(a);
+
+ return 0;
+}
+
+static void toggle_dcs_pcs(void)
+{
+ pcs = !pcs;
+ refresh_display();
+}
+
+static void toggle_up_down(void)
+{
+ uplink = !uplink;
+ refresh_display();
+
+ if (mode == MODE_SYNC && cursor < 0)
+ request_ul_levels(ul_arfcn);
+}
+
+static void toggle_spectrum(void)
+{
+ if (mode == MODE_MAIN) {
+ mode = MODE_SPECTRUM;
+ pm_mode = PM_IDLE;
+ } else if (mode == MODE_SPECTRUM) {
+ mode = MODE_MAIN;
+ pm_mode = PM_IDLE;
+ }
+ l1s_reset();
+ l1s_reset_hw();
+ pm_count = 0;
+ refresh_display();
+}
+
+static void tone_inc_dec(int inc)
+{
+ if (inc) {
+ if (tone + 25 <= 255)
+ tone += 25;
+ } else {
+ if (tone - 25 >= 0)
+ tone -= 25;
+ }
+
+ refresh_display();
+}
+
+static void hold_max(void)
+{
+ max = !max;
+ max_power = power;
+ refresh_display();
+}
+
+static int inc_dec_neighbour(int inc)
+{
+ if (inc) {
+ if (cursor > 0 && cursor - 1 >= (nb_num - NEIGH_LINES))
+ return -EINVAL;
+ cursor++;
+ } else {
+ if (cursor < 0)
+ return -EINVAL;
+ cursor--;
+ }
+
+ refresh_display();
+
+ return 0;
+}
+
+static int inc_dec_spectrum(int inc)
+{
+ if (inc) {
+ pm_scale <<= 1;
+ if (pm_scale > 8)
+ pm_scale = 8;
+ } else {
+ pm_scale >>= 1;
+ if (pm_scale < 1)
+ pm_scale = 1;
+ }
+
+ refresh_display();
+
+ return 0;
+}
+
+static void enter_sync(void);
+static void exit_sync(void);
+
+static void enter_rach(void);
+static void exit_rach(void);
+
+static void handle_key_code()
+{
+ /* key repeat */
+ if (key_pressed) {
+ unsigned long elapsed = jiffies - key_pressed_when;
+ if (elapsed > key_pressed_delay) {
+ key_pressed_when = jiffies;
+ key_pressed_delay = HZ / 10;
+ /* only repeat these keys */
+ if (key_pressed_code == KEY_LEFT
+ || key_pressed_code == KEY_RIGHT)
+ key_code = key_pressed_code;
+ }
+ }
+
+ if (key_code == KEY_INV)
+ return;
+
+ /* do later, do not disturb tone */
+ if (tone_on)
+ return;
+
+ switch (key_code) {
+ case KEY_0:
+ case KEY_1:
+ case KEY_2:
+ case KEY_3:
+ case KEY_4:
+ case KEY_5:
+ case KEY_6:
+ case KEY_7:
+ case KEY_8:
+ case KEY_9:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM || mode == MODE_ARFCN)
+ enter_arfcn(key_code);
+ break;
+ case KEY_UP:
+ if (mode == MODE_MAIN)
+ tone_inc_dec(1);
+ else if (mode == MODE_SYNC)
+ inc_dec_neighbour(0);
+ else if (mode == MODE_SPECTRUM)
+ inc_dec_spectrum(1);
+ break;
+ case KEY_DOWN:
+ if (mode == MODE_MAIN)
+ tone_inc_dec(0);
+ else if (mode == MODE_SYNC)
+ inc_dec_neighbour(1);
+ else if (mode == MODE_SPECTRUM)
+ inc_dec_spectrum(0);
+ break;
+ case KEY_RIGHT:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM)
+ inc_dec_arfcn(1);
+ else if (mode == MODE_SYNC && cursor < 0)
+ inc_dec_ul_arfcn(1);
+ break;
+ case KEY_LEFT:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM)
+ inc_dec_arfcn(0);
+ else if (mode == MODE_SYNC && cursor < 0)
+ inc_dec_ul_arfcn(0);
+ break;
+ case KEY_LEFT_SB:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM)
+ toggle_dcs_pcs();
+ else if (mode == MODE_ARFCN)
+ enter_arfcn(key_code);
+ else if (mode == MODE_SYNC)
+ exit_sync();
+ else if (mode == MODE_RACH)
+ exit_rach();
+ break;
+ case KEY_RIGHT_SB:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM)
+ toggle_up_down();
+ else if (mode == MODE_ARFCN)
+ enter_arfcn(key_code);
+ else if (mode == MODE_SYNC && cursor < 0)
+ toggle_up_down();
+ break;
+ case KEY_OK:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM)
+ enter_sync();
+ else if (mode == MODE_SYNC || mode == MODE_RACH)
+ enter_rach();
+ break;
+ case KEY_MENU:
+ hold_max();
+ break;
+ case KEY_POWER:
+ if (mode == MODE_ARFCN)
+ exit_arfcn();
+ else if (mode == MODE_SYNC)
+ exit_sync();
+ else if (mode == MODE_RACH)
+ exit_rach();
+ else if (mode == MODE_SPECTRUM)
+ toggle_spectrum();
+ break;
+ case KEY_STAR:
+ if (mode == MODE_MAIN || mode == MODE_SPECTRUM)
+ toggle_spectrum();
+ break;
+ default:
+ break;
+ }
+
+ key_code = KEY_INV;
+}
+
+static void handle_tone(void)
+{
+ unsigned long elapsed = jiffies - tone_time;
+
+ if (!tone_on) {
+ if (!tone || mode != MODE_MAIN)
+ return;
+ /* wait depending on power level */
+ if (elapsed < (uint8_t)(63-power))
+ return;
+ buzzer_volume(tone);
+ buzzer_note(NOTE(NOTE_C, OCTAVE_5));
+ tone_time = jiffies;
+ tone_on = 1;
+ return;
+ }
+
+ if (elapsed >= TONE_JIFFIES) {
+ tone_on = 0;
+ tone_time = jiffies;
+ buzzer_volume(0);
+ }
+}
+
+/* PM handling */
+
+static void handle_pm(void)
+{
+ /* start power measurement */
+ if (pm_mode == PM_IDLE && (mode == MODE_MAIN || mode == MODE_SPECTRUM)) {
+ struct msgb *msg = l1ctl_msgb_alloc(L1CTL_PM_REQ);
+ struct l1ctl_pm_req *pm;
+ uint16_t a, e;
+
+ pm = (struct l1ctl_pm_req *) msgb_put(msg, sizeof(*pm));
+ pm->type = 1;
+ if (mode == MODE_MAIN) {
+ a = arfcn;
+ if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX)
+ a |= ARFCN_PCS;
+ if (uplink)
+ a |= ARFCN_UPLINK;
+ e = a;
+ pm_mode = PM_SENT;
+ }
+ if (mode == MODE_SPECTRUM) {
+ if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX) {
+ a = PCS_MIN | ARFCN_PCS;
+ e = PCS_MAX | ARFCN_PCS;
+ } else {
+ a = band->min;
+ e = band->max;
+ }
+ pm_mode = PM_RANGE_SENT;
+ }
+ if (uplink) {
+ a |= ARFCN_UPLINK;
+ e |= ARFCN_UPLINK;
+ }
+ pm->range.band_arfcn_from = htons(a);
+ pm->range.band_arfcn_to = htons(e);
+
+ l1a_l23_rx(SC_DLCI_L1A_L23, msg);
+
+ return;
+ }
+
+ if (pm_mode == PM_RESULT) {
+ pm_mode = PM_IDLE;
+ if (pm_count == pm_max) {
+ int i = 0;
+ int sum = 0;
+
+ if (uplink) {
+ /* find max */
+ for (i = 0; i < pm_count; i++) {
+ if (pm_meas[i] > sum)
+ sum = pm_meas[i];
+ }
+ power = sum;
+ } else {
+ for (i = 0; i < pm_count; i++)
+ sum += pm_meas[i];
+ power = sum / pm_count;
+ }
+ if (power > max_power)
+ max_power = power;
+ pm_count = 0;
+ pm_max = (uplink) ? NUM_PM_UL : NUM_PM_DL;
+ if (!tone_on)
+ refresh_display();
+ }
+ return;
+ }
+
+ if (pm_mode == PM_RANGE_RESULT) {
+ pm_mode = PM_IDLE;
+ refresh_display();
+ buzzer_volume(tone);
+ buzzer_note(NOTE(NOTE_C, OCTAVE_5));
+ tone_time = jiffies;
+ tone_on = 1;
+ return;
+ }
+}
+
+/* sync / SI */
+
+static void enter_sync(void)
+{
+ struct msgb *msg = l1ctl_msgb_alloc(L1CTL_FBSB_REQ);
+ struct l1ctl_fbsb_req *req;
+ uint16_t a = arfcn;
+
+ l1s_reset();
+ l1s_reset_hw();
+ pm_count = 0;
+ pm_mode = PM_IDLE;
+
+ req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req));
+ if (pcs && arfcn >= PCS_MIN && arfcn <= PCS_MAX)
+ a |= ARFCN_PCS;
+ req->band_arfcn = htons(a);
+ req->timeout = htons(100);
+ /* Threshold when to consider FB_MODE1: 4kHz - 1kHz */
+ req->freq_err_thresh1 = htons(11000 - 1000);
+ /* Threshold when to consider SCH: 1kHz - 200Hz */
+ req->freq_err_thresh2 = htons(1000 - 200);
+ /* not used yet! */
+ req->num_freqerr_avg = 3;
+ req->flags = L1CTL_FBSB_F_FB01SB;
+ req->sync_info_idx = 0;
+ req->ccch_mode = CCCH_MODE_NONE;
+ l1a_l23_rx(SC_DLCI_L1A_L23, msg);
+
+ mode = MODE_SYNC;
+ memset(ul_levels, 0, sizeof(ul_levels));
+ si_new = 0;
+ ul_new = 0;
+ ul_arfcn = arfcn;
+ si_1[2] = 0;
+ si_2[2] = 0;
+ si_2bis[2] = 0;
+ si_2ter[2] = 0;
+ si_3[2] = 0;
+ si_4[2] = 0;
+ mcc = mnc = lac = 0;
+ ccch_conf = -1;
+ memset(freq, 0, sizeof(freq));
+ cursor = 0;
+ nb_num = 0;
+ sync_msg = "trying";
+ refresh_display();
+}
+
+static void exit_sync(void)
+{
+ l1s_reset();
+ l1s_reset_hw();
+ pm_count = 0;
+ pm_mode = PM_IDLE;
+ mode = MODE_MAIN;
+}
+
+int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *_mcc,
+uint16_t *_mnc, uint16_t *_lac)
+{
+ *_mcc = ((lai->digits[0] & 0x0f) << 8)
+ | (lai->digits[0] & 0xf0)
+ | (lai->digits[1] & 0x0f);
+ *_mnc = ((lai->digits[2] & 0x0f) << 8)
+ | (lai->digits[2] & 0xf0)
+ | ((lai->digits[1] & 0xf0) >> 4);
+ *_lac = ntohs(lai->lac);
+
+ return 0;
+}
+
+static void request_ul_levels(uint16_t a)
+{
+ struct msgb *msg = l1ctl_msgb_alloc(L1CTL_NEIGH_PM_REQ);
+ struct l1ctl_neigh_pm_req *pm_req =
+ (struct l1ctl_neigh_pm_req *) msgb_put(msg, sizeof(*pm_req));
+ int i;
+
+ if (pcs && a >= PCS_MIN && a <= PCS_MAX)
+ a |= ARFCN_PCS;
+ if (uplink)
+ a |= ARFCN_UPLINK;
+ pm_req->n = 8;
+ for (i = 0; i < 8; i++) {
+ pm_req->band_arfcn[i] = htons(a);
+ pm_req->tn[i] = i;
+ }
+ l1a_l23_rx(SC_DLCI_L1A_L23, msg);
+}
+
+static void handle_sync(void)
+{
+ struct gsm48_system_information_type_1 *si1;
+ struct gsm48_system_information_type_2 *si2;
+ struct gsm48_system_information_type_2bis *si2bis;
+ struct gsm48_system_information_type_2ter *si2ter;
+ struct gsm48_system_information_type_3 *si3;
+ struct gsm48_system_information_type_4 *si4;
+
+ if (mode != MODE_SYNC)
+ return;
+
+ /* once we synced, we take the result and request UL measurement */
+ if (sync_result) {
+ uint16_t a = ul_arfcn;
+
+ sync_msg = sync_result;
+ sync_result = NULL;
+ refresh_display();
+
+ if (sync_msg[0] != 'o')
+ return;
+
+ request_ul_levels(a);
+
+ return;
+ }
+
+ if (tone_on)
+ return;
+
+ /* no UL result, no SI result */
+ if (!ul_new && !(si_new & 0x100))
+ return;
+
+ /* new UL result */
+ if (ul_new) {
+ ul_new = 0;
+ if (cursor < 0)
+ refresh_display();
+ return;
+ }
+
+ /* decode si */
+ switch (si_new & 0xff) {
+ case GSM48_MT_RR_SYSINFO_1:
+ si1 = (struct gsm48_system_information_type_1 *)si_1;
+ gsm48_decode_freq_list(freq, si1->cell_channel_description,
+ sizeof(si1->cell_channel_description), 0xce,
+ FREQ_TYPE_SERV);
+ break;
+ case GSM48_MT_RR_SYSINFO_2:
+ si2 = (struct gsm48_system_information_type_2 *)si_2;
+ gsm48_decode_freq_list(freq, si2->bcch_frequency_list,
+ sizeof(si2->bcch_frequency_list), 0xce,
+ FREQ_TYPE_NCELL_2);
+ break;
+ case GSM48_MT_RR_SYSINFO_2bis:
+ si2bis = (struct gsm48_system_information_type_2bis *)si_2bis;
+ gsm48_decode_freq_list(freq, si2bis->bcch_frequency_list,
+ sizeof(si2bis->bcch_frequency_list), 0xce,
+ FREQ_TYPE_NCELL_2bis);
+ break;
+ case GSM48_MT_RR_SYSINFO_2ter:
+ si2ter = (struct gsm48_system_information_type_2ter *)si_2ter;
+ gsm48_decode_freq_list(freq, si2ter->ext_bcch_frequency_list,
+ sizeof(si2ter->ext_bcch_frequency_list), 0x8e,
+ FREQ_TYPE_NCELL_2ter);
+ break;
+ case GSM48_MT_RR_SYSINFO_3:
+ si3 = (struct gsm48_system_information_type_3 *)si_3;
+ gsm48_decode_lai(&si3->lai, &mcc, &mnc, &lac);
+ cell_id = ntohs(si3->cell_identity);
+ if (ccch_conf < 0) {
+ struct msgb *msg =
+ l1ctl_msgb_alloc(L1CTL_CCCH_MODE_REQ);
+ struct l1ctl_ccch_mode_req *req =
+ (struct l1ctl_ccch_mode_req *)
+ msgb_put(msg, sizeof(*req));
+
+ ccch_conf = si3->control_channel_desc.ccch_conf;
+ req->ccch_mode = (ccch_conf == 1)
+ ? CCCH_MODE_COMBINED
+ : CCCH_MODE_NON_COMBINED;
+ printf("ccch_mode=%d\n", ccch_conf);
+
+ l1a_l23_rx(SC_DLCI_L1A_L23, msg);
+ }
+ break;
+ case GSM48_MT_RR_SYSINFO_4:
+ si4 = (struct gsm48_system_information_type_4 *)si_4;
+ gsm48_decode_lai(&si4->lai, &mcc, &mnc, &lac);
+ break;
+ }
+
+ if (cursor >= 0)
+ refresh_display();
+
+ /* tone depends on successfully received BCCH */
+ buzzer_volume(tone);
+ tone_time = jiffies;
+ tone_on = 1;
+ if ((si_new & 0xff) == 0xff)
+ buzzer_note(NOTE(NOTE_C, OCTAVE_2));
+ else
+ buzzer_note(NOTE(NOTE_C, OCTAVE_5));
+ si_new = 0;
+}
+
+static void enter_rach(void)
+{
+ if (ccch_conf < 0)
+ return;
+
+ if (rach)
+ return;
+
+#ifndef CONFIG_TX_ENABLE
+ assign = ASSIGN_NO_TX;
+ mode = MODE_RACH;
+ /* display refresh is done by rach handler */
+#else
+ struct msgb *msg1 = l1ctl_msgb_alloc(L1CTL_NEIGH_PM_REQ);
+ struct msgb *msg2 = l1ctl_msgb_alloc(L1CTL_RACH_REQ);
+ struct l1ctl_neigh_pm_req *pm_req = (struct l1ctl_neigh_pm_req *)
+ msgb_put(msg1, sizeof(*pm_req));
+ struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *)
+ msgb_put(msg2, sizeof(*ul));;
+ struct l1ctl_rach_req *rach_req = (struct l1ctl_rach_req *)
+ msgb_put(msg2, sizeof(*rach_req));
+
+ l1s.tx_power = 0;
+
+ pm_req->n = 0; /* disable */
+
+ rach_ra = 0x00;
+ rach_req->ra = rach_ra;
+ rach_req->offset = 0;
+ rach_req->combined = (ccch_conf == 1);
+
+ l1a_l23_rx(SC_DLCI_L1A_L23, msg1);
+ l1a_l23_rx(SC_DLCI_L1A_L23, msg2);
+ rach = 1;
+ rach_when = jiffies;
+ assign = ASSIGN_NONE;
+ mode = MODE_RACH;
+ refresh_display();
+#endif
+
+}
+
+static void exit_rach(void)
+{
+ rach = 0;
+
+ request_ul_levels(ul_arfcn);
+
+ mode = MODE_SYNC;
+ refresh_display();
+}
+
+static void handle_assign(void)
+{
+ if (mode != MODE_RACH)
+ return;
+
+ if (assign == ASSIGN_NONE) {
+ unsigned long elapsed = jiffies - rach_when;
+
+ if (!rach)
+ return;
+ if (elapsed < HZ * 2)
+ return;
+ assign = ASSIGN_TIMEOUT;
+ rach = 0;
+ }
+
+ refresh_display();
+ assign = ASSIGN_NONE;
+}
+
+/* Main Program */
+const char *hr = "======================================================================\n";
+
+/* match request reference agains request history */
+static int gsm48_match_ra(struct gsm48_req_ref *ref)
+{
+ uint8_t ia_t1, ia_t2, ia_t3;
+ uint8_t cr_t1, cr_t2, cr_t3;
+
+ if (rach && ref->ra == rach_ra) {
+ ia_t1 = ref->t1;
+ ia_t2 = ref->t2;
+ ia_t3 = (ref->t3_high << 3) | ref->t3_low;
+ ref = &rach_ref;
+ cr_t1 = ref->t1;
+ cr_t2 = ref->t2;
+ cr_t3 = (ref->t3_high << 3) | ref->t3_low;
+ if (ia_t1 == cr_t1 && ia_t2 == cr_t2 && ia_t3 == cr_t3)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* note: called from IRQ context */
+static void rx_imm_ass(struct msgb *msg)
+{
+ struct gsm48_imm_ass *ia = msgb_l3(msg);
+
+ if (gsm48_match_ra(&ia->req_ref)) {
+ assign = ASSIGN_RESULT;
+ ta = ia->timing_advance;
+ rach = 0;
+ }
+}
+
+/* note: called from IRQ context */
+static void rx_imm_ass_ext(struct msgb *msg)
+{
+ struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
+
+ if (gsm48_match_ra(&ia->req_ref1)) {
+ assign = ASSIGN_RESULT;
+ ta = ia->timing_advance1;
+ rach = 0;
+ }
+ if (gsm48_match_ra(&ia->req_ref2)) {
+ assign = ASSIGN_RESULT;
+ ta = ia->timing_advance2;
+ rach = 0;
+ }
+}
+
+/* note: called from IRQ context */
+static void rx_imm_ass_rej(struct msgb *msg)
+{
+ struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
+ struct gsm48_req_ref *req_ref;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ /* request reference */
+ req_ref = (struct gsm48_req_ref *)
+ (((uint8_t *)&ia->req_ref1) + i * 4);
+ if (gsm48_match_ra(req_ref)) {
+ assign = ASSIGN_REJECT;
+ rach = 0;
+ }
+ }
+}
+
+/* note: called from IRQ context */
+static void rx_pch_agch(struct msgb *msg)
+{
+ struct gsm48_system_information_type_header *sih;
+
+ /* store SI */
+ sih = msgb_l3(msg);
+ switch (sih->system_information) {
+ case GSM48_MT_RR_IMM_ASS:
+ rx_imm_ass(msg);
+ break;
+ case GSM48_MT_RR_IMM_ASS_EXT:
+ rx_imm_ass_ext(msg);
+ break;
+ case GSM48_MT_RR_IMM_ASS_REJ:
+ rx_imm_ass_rej(msg);
+ break;
+ }
+}
+
+/* note: called from IRQ context */
+static void rx_bcch(struct msgb *msg)
+{
+ struct gsm48_system_information_type_header *sih;
+
+ /* store SI */
+ sih = msgb_l3(msg);
+ switch (sih->system_information) {
+ case GSM48_MT_RR_SYSINFO_1:
+ memcpy(si_1, msgb_l3(msg), msgb_l3len(msg));
+ break;
+ case GSM48_MT_RR_SYSINFO_2:
+ memcpy(si_2, msgb_l3(msg), msgb_l3len(msg));
+ break;
+ case GSM48_MT_RR_SYSINFO_2bis:
+ memcpy(si_2bis, msgb_l3(msg), msgb_l3len(msg));
+ break;
+ case GSM48_MT_RR_SYSINFO_2ter:
+ memcpy(si_2ter, msgb_l3(msg), msgb_l3len(msg));
+ break;
+ case GSM48_MT_RR_SYSINFO_3:
+ memcpy(si_3, msgb_l3(msg), msgb_l3len(msg));
+ break;
+ case GSM48_MT_RR_SYSINFO_4:
+ memcpy(si_4, msgb_l3(msg), msgb_l3len(msg));
+ break;
+ }
+ si_new = sih->system_information | 0x100;
+}
+
+/* note: called from IRQ context */
+static void l1a_l23_tx(struct msgb *msg)
+{
+ struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->l1h;
+ struct l1ctl_pm_conf *pmr;
+ struct l1ctl_info_dl *dl;
+ struct l1ctl_fbsb_conf *sb;
+ uint8_t chan_type, chan_ts, chan_ss;
+ struct l1ctl_neigh_pm_ind *pm_ind;
+ struct gsm_time tm;
+
+ switch (l1h->msg_type) {
+ case L1CTL_PM_CONF:
+ if (pm_mode == PM_SENT) {
+ pmr = (struct l1ctl_pm_conf *) l1h->data;
+ pm_meas[pm_count] = pmr->pm[0];
+ pm_count++;
+ pm_mode = PM_RESULT;
+ }
+ if (pm_mode == PM_RANGE_SENT) {
+ for (pmr = (struct l1ctl_pm_conf *) l1h->data;
+ (uint8_t *) pmr < msg->tail; pmr++) {
+ if (!max || pm_spectrum[ntohs(pmr->band_arfcn) & 1023] < pmr->pm[0])
+ pm_spectrum[ntohs(pmr->band_arfcn) & 1023] = pmr->pm[0];
+ }
+ if ((l1h->flags & L1CTL_F_DONE))
+ pm_mode = PM_RANGE_RESULT;
+ }
+ l1s.tpu_offset_correction += 5000 / NUM_PM_UL;
+ break;
+ case L1CTL_FBSB_CONF:
+ dl = (struct l1ctl_info_dl *) l1h->data;
+ sb = (struct l1ctl_fbsb_conf *) dl->payload;
+ if (sb->result == 0)
+ sync_result = "ok";
+ else
+ sync_result = "error";
+ bsic = sb->bsic;
+ break;
+ case L1CTL_DATA_IND:
+ dl = (struct l1ctl_info_dl *) l1h->data;
+ msg->l2h = dl->payload;
+ rsl_dec_chan_nr(dl->chan_nr, &chan_type, &chan_ss, &chan_ts);
+
+ power = dl->rx_level;
+ if (dl->fire_crc >= 2) {
+ if (chan_type == RSL_CHAN_BCCH)
+ si_new = 0x1ff; /* error frame indication */
+ break; /* free, but don't send to sercom */
+ }
+
+ switch (chan_type) {
+ case RSL_CHAN_BCCH:
+ msg->l3h = msg->l2h;
+ rx_bcch(msg);
+ break;
+ case RSL_CHAN_PCH_AGCH:
+ msg->l3h = msg->l2h;
+ rx_pch_agch(msg);
+ break;
+ }
+ sercomm_sendmsg(SC_DLCI_L1A_L23, msg);
+ return; /* msg is freed by sercom */
+ case L1CTL_NEIGH_PM_IND:
+ for (pm_ind = (struct l1ctl_neigh_pm_ind *) l1h->data;
+ (uint8_t *) pm_ind < msg->tail; pm_ind++) {
+ ul_levels[pm_ind->tn] = pm_ind->pm[0];
+ /* hold max only, if max enabled and level is lower */
+ if (!max || ul_levels[pm_ind->tn] > ul_max[pm_ind->tn])
+ ul_max[pm_ind->tn] = ul_levels[pm_ind->tn];
+ if (pm_ind->tn == 7)
+ ul_new = 1;
+ }
+ break;
+ case L1CTL_RACH_CONF:
+ dl = (struct l1ctl_info_dl *) l1h->data;
+ gsm_fn2gsmtime(&tm, ntohl(dl->frame_nr));
+ rach_ref.t1 = tm.t1;
+ rach_ref.t2 = tm.t2;
+ rach_ref.t3_low = tm.t3 & 0x7;
+ rach_ref.t3_high = tm.t3 >> 3;
+ break;
+ }
+
+ msgb_free(msg);
+
+}
+
+static void console_rx_cb(uint8_t dlci, struct msgb *msg)
+{
+ if (dlci != SC_DLCI_CONSOLE) {
+ printf("Message for unknown DLCI %u\n", dlci);
+ return;
+ }
+
+ printf("Message on console DLCI: '%s'\n", msg->data);
+ msgb_free(msg);
+}
+
+static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
+{
+ int i;
+ printf("l1a_l23_rx_cb (DLCI %d): ", dlci);
+ for (i = 0; i < msg->len; i++)
+ printf("%02x ", msg->data[i]);
+ puts("\n");
+}
+
+static void key_handler(enum key_codes code, enum key_states state)
+{
+ if (state != PRESSED) {
+ key_pressed = 0;
+ return;
+ }
+ /* key repeat */
+ if (!key_pressed) {
+ key_pressed = 1;
+ key_pressed_when = jiffies;
+ key_pressed_code = code;
+ key_pressed_delay = HZ * 6 / 10;
+ }
+
+ key_code = code;
+}
+
+int main(void)
+{
+ board_init();
+
+ puts("\n\nOSMOCOM Monitor Tool (revision " GIT_REVISION ")\n");
+ puts(hr);
+
+ /* Dump device identification */
+ dump_dev_id();
+ puts(hr);
+
+ /* Dump clock config before PLL set */
+ calypso_clk_dump();
+ puts(hr);
+
+ keypad_set_handler(&key_handler);
+
+ /* Dump clock config after PLL set */
+ calypso_clk_dump();
+ puts(hr);
+
+ sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
+ sercomm_register_rx_cb(SC_DLCI_L1A_L23, l1a_l23_rx_cb);
+
+ layer1_init();
+ l1a_l23_tx_cb = l1a_l23_tx;
+
+// display_unset_attr(DISP_ATTR_INVERT);
+
+ tpu_frame_irq_en(1, 1);
+
+ buzzer_mode_pwt(1);
+ buzzer_volume(0);
+
+ memset(pm_spectrum, 0, sizeof(pm_spectrum));
+ memset(ul_max, 0, sizeof(ul_max));
+
+ /* inc 0 to 1 and refresh */
+ inc_dec_arfcn(1);
+
+ while (1) {
+ l1a_compl_execute();
+ osmo_timers_update();
+ handle_key_code();
+ l1a_l23_handler();
+ handle_pm();
+ handle_sync();
+ handle_assign();
+ handle_tone();
+ }
+
+ /* NOT REACHED */
+
+ twl3025_power_off();
+}
+
diff --git a/Src/osmolib/src/target/firmware/apps/simtest/main.c b/Src/osmolib/src/target/firmware/apps/simtest/main.c
index 83f708e..3272b57 100644..100755
--- a/Src/osmolib/src/target/firmware/apps/simtest/main.c
+++ b/Src/osmolib/src/target/firmware/apps/simtest/main.c
@@ -31,7 +31,6 @@
#include <keypad.h>
#include <board.h>
#include <abb/twl3025.h>
-#include <display.h>
#include <rf/trf6151.h>
#include <calypso/clock.h>
#include <calypso/tpu.h>
@@ -52,14 +51,14 @@ static void myHexdump(uint8_t *data, int len)
int i;
for(i=0;i<len;i++)
- printf("%x ",data[i]);
+ printf("%02x ",data[i]);
printf("(%i bytes)\n", len);
return;
}
-/* SIM instructions
+/* SIM instructions
All instructions a standard sim card must feature: */
#define SIM_CLASS 0xA0 /* Class that contains the following instructions */
#define SIM_SELECT 0xA4 /* Select a file on the card */
@@ -135,7 +134,7 @@ uint16_t sim_select(uint16_t fid)
}
/* Get the status of the currently selected file */
-uint16_t sim_status(void)
+uint16_t sim_status(void)
{
uint8_t status_word[2];
@@ -158,6 +157,55 @@ uint16_t sim_readbinary(uint8_t offset_high, uint8_t offset_low, uint8_t length,
return (status_word[0] << 8) | status_word[1];
}
+uint16_t sim_verify(char *pin)
+{
+ uint8_t txBuffer[8];
+ uint8_t status_word[2];
+
+ memset(txBuffer, 0xFF, 8);
+ memcpy(txBuffer, pin, strlen(pin));
+
+ if(calypso_sim_transceive(SIM_CLASS, SIM_VERIFY_CHV, 0x00, 0x01, 0x08, txBuffer,status_word, SIM_APDU_PUT) != 0)
+ return 0xFFFF;
+
+ return (status_word[0] << 8) | status_word[1];
+}
+
+uint16_t sim_run_gsm_algorith(uint8_t *data)
+{
+ uint8_t status_word[2];
+
+ if(calypso_sim_transceive(SIM_CLASS, SIM_RUN_GSM_ALGORITHM, 0x00, 0x00, 0x10, data, status_word, SIM_APDU_PUT) != 0)
+ return 0xFFFF;
+
+ printf(" ==> Status word: %x\n", (status_word[0] << 8) | status_word[1]);
+
+ if(status_word[0] != 0x9F || status_word[1] != 0x0C)
+ return (status_word[0] << 8) | status_word[1];
+
+ /* GET RESPONSE */
+
+ if(calypso_sim_transceive(SIM_CLASS, SIM_GET_RESPONSE, 0, 0, 0x0C, data ,status_word, SIM_APDU_GET) != 0)
+ return 0xFFFF;
+
+ return (status_word[0] << 8) | status_word[1];
+}
+
+
+/* FIXME: We need proper calibrated delay loops at some point! */
+void delay_us(unsigned int us)
+{
+ volatile unsigned int i;
+
+ for (i= 0; i < us*4; i++) { i; }
+}
+
+void delay_ms(unsigned int ms)
+{
+ volatile unsigned int i;
+ for (i= 0; i < ms*1300; i++) { i; }
+}
+
/* Execute my (dexter's) personal test */
void do_sim_test(void)
{
@@ -171,7 +219,7 @@ void do_sim_test(void)
uint8_t atr[20];
uint8_t atrLength = 0;
-
+
memset(atr,0,sizeof(atr));
@@ -185,7 +233,7 @@ void do_sim_test(void)
/* Initialize Sim-Controller driver */
puts("Initializing driver:\n");
- calypso_sim_init();
+ calypso_sim_init(NULL);
/* Power up sim and display ATR */
puts("Power up simcard:\n");
@@ -215,6 +263,9 @@ void do_sim_test(void)
puts(" * Testing SELECT: Selecting DF_GSM\n");
printf(" ==> Status word: %x\n", sim_select(SIM_DF_GSM));
+ puts(" * Testing PIN VERIFY\n");
+ printf(" ==> Status word: %x\n", sim_verify("1234"));
+
puts(" * Testing SELECT: Selecting EF_IMSI\n");
printf(" ==> Status word: %x\n", sim_select(SIM_EF_IMSI));
@@ -222,11 +273,18 @@ void do_sim_test(void)
printf(" ==> Status word: %x\n", sim_status());
memset(buffer,0,sizeof(buffer));
- puts(" * Testing READ BINARY:\n");
+ puts(" * Testing READ BINARY:\n");
printf(" ==> Status word: %x\n", sim_readbinary(0,0,9,buffer));
printf(" Data: ");
myHexdump(buffer,9);
+ memset(buffer,0,sizeof(buffer));
+ memcpy(buffer,"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff",16);
+ puts(" * Testing RUN GSM ALGORITHM\n");
+ printf(" ==> Status word: %x\n", sim_run_gsm_algorith(buffer));
+ printf(" Result: ");
+ myHexdump(buffer,12);
+
delay_ms(5000);
calypso_sim_powerdown();
@@ -279,9 +337,6 @@ int main(void)
puts(hr);
#endif
- display_set_attr(DISP_ATTR_INVERT);
- display_puts("SIM-TEST");
-
sercomm_register_rx_cb(SC_DLCI_CONSOLE, console_rx_cb);
do_sim_test();
diff --git a/Src/osmolib/src/target/firmware/board/compal/highram.lds b/Src/osmolib/src/target/firmware/board/compal/highram.lds
index 1f0a5a6..498a2fa 100644
--- a/Src/osmolib/src/target/firmware/board/compal/highram.lds
+++ b/Src/osmolib/src/target/firmware/board/compal/highram.lds
@@ -16,9 +16,9 @@ MEMORY
/* lowram: could be anything, we place exception vectors here */
XRAM (rw) : ORIGIN = 0x00800000, LENGTH = 0x00020000
/* highram binary: our text, initialized data */
- LRAM (rw) : ORIGIN = 0x00820000, LENGTH = 0x00010000
+ LRAM (rw) : ORIGIN = 0x00820000, LENGTH = 0x00014000
/* highram binary: our unitialized data, stacks, heap */
- IRAM (rw) : ORIGIN = 0x00830000, LENGTH = 0x00010000
+ IRAM (rw) : ORIGIN = 0x00834000, LENGTH = 0x0000c000
}
SECTIONS
{
diff --git a/Src/osmolib/src/target/firmware/board/compal/ram.lds b/Src/osmolib/src/target/firmware/board/compal/ram.lds
index 342870d..9503ede 100644
--- a/Src/osmolib/src/target/firmware/board/compal/ram.lds
+++ b/Src/osmolib/src/target/firmware/board/compal/ram.lds
@@ -11,9 +11,9 @@ ENTRY(_start)
MEMORY
{
/* compal-loaded binary: our text, initialized data */
- LRAM (rw) : ORIGIN = 0x00800000, LENGTH = 0x00010000
+ LRAM (rw) : ORIGIN = 0x00800000, LENGTH = 0x00014000
/* compal-loaded binary: our unitialized data, stacks, heap */
- IRAM (rw) : ORIGIN = 0x00810000, LENGTH = 0x00010000
+ IRAM (rw) : ORIGIN = 0x00814000, LENGTH = 0x0000c000
}
SECTIONS
{
diff --git a/Src/osmolib/src/target/firmware/board/compal_e86/init.c b/Src/osmolib/src/target/firmware/board/compal_e86/init.c
index 1de6193..2d463cb 100644
--- a/Src/osmolib/src/target/firmware/board/compal_e86/init.c
+++ b/Src/osmolib/src/target/firmware/board/compal_e86/init.c
@@ -41,10 +41,12 @@
#include <calypso/backlight.h>
#include <comm/sercomm.h>
+#include <comm/timer.h>
#include <abb/twl3025.h>
#include <rf/trf6151.h>
-#include <display.h>
+
+#include <fb/framebuffer.h>
#define ARMIO_LATCH_OUT 0xfffe4802
#define IO_CNTL_REG 0xfffe4804
@@ -127,8 +129,7 @@ void board_init(void)
timer_init();
/* Initialize LCD driver (uses UWire) */
- display = &td014_display;
- display_init();
+ fb_init();
bl_mode_pwl(1);
bl_level(0);
diff --git a/Src/osmolib/src/target/firmware/board/compal_e88/init.c b/Src/osmolib/src/target/firmware/board/compal_e88/init.c
index a5bf880..fe3fd72 100644
--- a/Src/osmolib/src/target/firmware/board/compal_e88/init.c
+++ b/Src/osmolib/src/target/firmware/board/compal_e88/init.c
@@ -44,7 +44,7 @@
#include <abb/twl3025.h>
#include <rf/trf6151.h>
-#include <display.h>
+#include <fb/framebuffer.h>
#define ARMIO_LATCH_OUT 0xfffe4802
#define IO_CNTL_REG 0xfffe4804
@@ -123,8 +123,8 @@ void board_init(void)
timer_init();
/* Initialize LCD driver (uses I2C) and backlight */
- display = &st7558_display;
- display_init();
+ fb_init();
+
bl_mode_pwl(1);
bl_level(50);
diff --git a/Src/osmolib/src/target/firmware/board/compal_e99/init.c b/Src/osmolib/src/target/firmware/board/compal_e99/init.c
index 0c218a8..31eb978 100644
--- a/Src/osmolib/src/target/firmware/board/compal_e99/init.c
+++ b/Src/osmolib/src/target/firmware/board/compal_e99/init.c
@@ -41,10 +41,12 @@
#include <calypso/backlight.h>
#include <comm/sercomm.h>
+#include <comm/timer.h>
#include <abb/twl3025.h>
#include <rf/trf6151.h>
-#include <display.h>
+
+#include <fb/framebuffer.h>
#define ARMIO_LATCH_OUT 0xfffe4802
#define IO_CNTL_REG 0xfffe4804
@@ -127,11 +129,11 @@ void board_init(void)
timer_init();
/* Initialize LCD driver (uses UWire) and backlight */
- display = &ssd1783_display;
- display_init();
bl_mode_pwl(1);
bl_level(50);
+ fb_init();
+
/* Initialize keypad driver */
keypad_init(1);
diff --git a/Src/osmolib/src/target/firmware/board/gta0x/init.c b/Src/osmolib/src/target/firmware/board/gta0x/init.c
index 4f256ea..d125e15 100644
--- a/Src/osmolib/src/target/firmware/board/gta0x/init.c
+++ b/Src/osmolib/src/target/firmware/board/gta0x/init.c
@@ -44,7 +44,6 @@
#include <abb/twl3025.h>
#include <rf/trf6151.h>
-#include <display.h>
#define ARMIO_LATCH_OUT 0xfffe4802
#define IO_CNTL_REG 0xfffe4804
@@ -123,8 +122,6 @@ void board_init(void)
timer_init();
/* Initialize LCD driver (uses I2C) and backlight */
- display = &st7558_display;
- display_init();
bl_mode_pwl(1);
bl_level(50);
diff --git a/Src/osmolib/src/target/firmware/board/pirelli_dpl10/init.c b/Src/osmolib/src/target/firmware/board/pirelli_dpl10/init.c
index 53fb257..ef18403 100644
--- a/Src/osmolib/src/target/firmware/board/pirelli_dpl10/init.c
+++ b/Src/osmolib/src/target/firmware/board/pirelli_dpl10/init.c
@@ -1,7 +1,7 @@
/* Initialization for the Pirelli DP-L10 */
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2011 by Steve Markgraf <steve@steve-m.de>
+ * (C) 2011-12 by Steve Markgraf <steve@steve-m.de>
*
* All Rights Reserved
*
@@ -45,10 +45,13 @@
#include <abb/twl3025.h>
#include <rf/trf6151.h>
-#include <display.h>
+
+#include <fb/framebuffer.h>
#define ARMIO_LATCH_OUT 0xfffe4802
+#define IO_CNTL_REG 0xfffe4804
#define ASIC_CONF_REG 0xfffef008
+#define IO_CONF_REG 0xfffef00a
static void board_io_init(void)
{
@@ -59,17 +62,36 @@ static void board_io_init(void)
reg |= ((1 << 12) | (1 << 7)); /* SCL / SDA */
/* TWL3025: Set SPI+RIF RX clock to rising edge */
reg |= (1 << 13) | (1 << 14);
+ reg &= ~(1 << 1);
writew(reg, ASIC_CONF_REG);
+
+ /* enable IO functionality */
+ reg = readw(IO_CONF_REG);
+ reg |= (1 << 9) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
+ writew(reg, IO_CONF_REG);
+
+ /* set IO directions */
+ reg = readw(IO_CNTL_REG);
+ reg &= ~((1 << 7) | (1 << 4) | (1 << 1));
+ writew(reg, IO_CNTL_REG);
+
+ /* reset display controller, disable bypass mode, set nCS4 to display */
+ reg = readw(ARMIO_LATCH_OUT);
+ reg &= ~(1 << 4);
+ writew(reg, ARMIO_LATCH_OUT);
+ reg &= ~(1 << 7);
+ reg |= (1 << 4) | (1 << 1);
+ writew(reg, ARMIO_LATCH_OUT);
}
void board_init(void)
{
/* Configure the memory interface */
- calypso_mem_cfg(CALYPSO_nCS0, 3, CALYPSO_MEM_16bit, 1);
- calypso_mem_cfg(CALYPSO_nCS1, 3, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS0, 4, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS1, 4, CALYPSO_MEM_16bit, 1);
calypso_mem_cfg(CALYPSO_nCS2, 5, CALYPSO_MEM_16bit, 1);
- calypso_mem_cfg(CALYPSO_nCS3, 5, CALYPSO_MEM_16bit, 1);
- calypso_mem_cfg(CALYPSO_CS4, 0, CALYPSO_MEM_8bit, 1);
+ calypso_mem_cfg(CALYPSO_nCS3, 4, CALYPSO_MEM_16bit, 1);
+ calypso_mem_cfg(CALYPSO_CS4, 7, CALYPSO_MEM_16bit, 1);
calypso_mem_cfg(CALYPSO_nCS6, 0, CALYPSO_MEM_32bit, 1);
calypso_mem_cfg(CALYPSO_nCS7, 0, CALYPSO_MEM_32bit, 0);
@@ -110,11 +132,11 @@ void board_init(void)
/* Initialize system timers (uses hwtimer 2) */
timer_init();
- /* Initialize LCD driver (uses I2C) and backlight */
- display = &st7558_display;
- display_init();
+ /* Initialize LCD driver and backlight (0 is max, 255 min brightness) */
bl_mode_pwl(1);
- bl_level(0);
+ bl_level(50);
+
+ fb_init();
/* Initialize keypad driver */
keypad_init(1);
diff --git a/Src/osmolib/src/target/firmware/board/se_j100/init.c b/Src/osmolib/src/target/firmware/board/se_j100/init.c
index 30c3e6b..2a3de0e 100644
--- a/Src/osmolib/src/target/firmware/board/se_j100/init.c
+++ b/Src/osmolib/src/target/firmware/board/se_j100/init.c
@@ -41,10 +41,12 @@
#include <calypso/backlight.h>
#include <comm/sercomm.h>
+#include <comm/timer.h>
#include <abb/twl3025.h>
#include <rf/trf6151.h>
-#include <display.h>
+
+#include <fb/framebuffer.h>
#define ARMIO_LATCH_OUT 0xfffe4802
#define IO_CNTL_REG 0xfffe4804
@@ -127,8 +129,7 @@ void board_init(void)
timer_init();
/* Initialize LCD driver (uses UWire) and backlight */
- display = &ssd1963_display;
- display_init();
+ fb_init();
bl_mode_pwl(1);
bl_level(50);
diff --git a/Src/osmolib/src/target/firmware/calypso/backlight.c b/Src/osmolib/src/target/firmware/calypso/backlight.c
index a18dcb9..cf29984 100644
--- a/Src/osmolib/src/target/firmware/calypso/backlight.c
+++ b/Src/osmolib/src/target/firmware/calypso/backlight.c
@@ -50,7 +50,7 @@ void bl_mode_pwl(int on)
writew(reg, ASIC_CONF_REG);
} else {
/* Switch pin from PWL to LT */
- reg |= ~ASCONF_PWL_ENA;
+ reg &= ~ASCONF_PWL_ENA;
writew(reg, ASIC_CONF_REG);
/* Disable pwl */
writeb(0x00, PWL_REG(PWL_CTRL));
diff --git a/Src/osmolib/src/target/firmware/calypso/i2c.c b/Src/osmolib/src/target/firmware/calypso/i2c.c
index 344424d..bf44178 100644
--- a/Src/osmolib/src/target/firmware/calypso/i2c.c
+++ b/Src/osmolib/src/target/firmware/calypso/i2c.c
@@ -67,9 +67,9 @@ int i2c_write(uint8_t chip, uint32_t addr, int alen, const uint8_t *buffer, int
if (len > 16)
return -1;
- printd("i2c_write(chip=0x%02u, addr=0x%02u): ", chip, addr)
+ printd("i2c_write(chip=0x%02u, addr=0x%02u): ", chip, addr);
- writeb(chip & 0x3f, I2C_REG(DEVICE_REG));
+ writeb(chip & 0x7f, I2C_REG(DEVICE_REG));
writeb(addr & 0xff, I2C_REG(ADDRESS_REG));
/* we have to tell the controller how many bits we'll put into the fifo ?!? */
@@ -91,7 +91,7 @@ int i2c_write(uint8_t chip, uint32_t addr, int alen, const uint8_t *buffer, int
/* wait until transfer completes */
while (1) {
uint8_t reg = readb(I2C_REG(STATUS_ACTIVITY_REG));
- printd("I2C Status: 0x%02x\n", rerg & 0xf);
+ printd("I2C Status: 0x%02x\n", reg & 0xf);
if (!(reg & I2C_STATUS_IDLE)) // 0: idle 1: not idle
break;
}
diff --git a/Src/osmolib/src/target/firmware/calypso/keypad.c b/Src/osmolib/src/target/firmware/calypso/keypad.c
index fd4e0ff..f2dea9d 100644
--- a/Src/osmolib/src/target/firmware/calypso/keypad.c
+++ b/Src/osmolib/src/target/firmware/calypso/keypad.c
@@ -31,6 +31,7 @@
#include <calypso/irq.h>
#include <abb/twl3025.h>
+#include <comm/timer.h>
#define KBR_LATCH_REG 0xfffe480a
@@ -44,16 +45,13 @@ void emit_key(uint8_t key, uint8_t state)
{
printf("key=%u %s\n", key, state == PRESSED ? "pressed" : "released");
- if (state == RELEASED)
- if (key == KEY_POWER)
- twl3025_power_off();
-
if(key_handler) {
key_handler(key, state);
}
}
volatile uint32_t lastbuttons = 0;
+unsigned long power_hold = 0;
#define BTN_TO_KEY(name) \
((diff & BTN_##name) == BTN_##name) \
@@ -67,6 +65,17 @@ void dispatch_buttons(uint32_t buttons)
{
uint8_t state;
+ if ((buttons & BTN_POWER)) {
+ /* hold button 500ms to shut down */
+ if ((lastbuttons & BTN_POWER)) {
+ unsigned long elapsed = jiffies - power_hold;
+ if (elapsed > 50)
+ twl3025_power_off();
+ power_hold++;
+ } else
+ power_hold = jiffies;
+ }
+
if (buttons == lastbuttons)
return;
diff --git a/Src/osmolib/src/target/firmware/calypso/rtc.c b/Src/osmolib/src/target/firmware/calypso/rtc.c
index ce750c2..45d759f 100644
--- a/Src/osmolib/src/target/firmware/calypso/rtc.c
+++ b/Src/osmolib/src/target/firmware/calypso/rtc.c
@@ -26,7 +26,6 @@
#include <defines.h>
#include <debug.h>
#include <memory.h>
-#include <display.h>
#include <calypso/irq.h>
#define BASE_ADDR_RTC 0xfffe1800
@@ -61,10 +60,6 @@ static int tick_ctr;
static void rtc_irq_tick(__unused enum irq_nr nr)
{
- if (tick_ctr & 1)
- display_set_attr(DISP_ATTR_INVERT);
- else
- display_unset_attr(DISP_ATTR_INVERT);
tick_ctr++;
}
diff --git a/Src/osmolib/src/target/firmware/calypso/sim.c b/Src/osmolib/src/target/firmware/calypso/sim.c
index a539cf8..752628f 100644
--- a/Src/osmolib/src/target/firmware/calypso/sim.c
+++ b/Src/osmolib/src/target/firmware/calypso/sim.c
@@ -1,6 +1,7 @@
/* Driver for Simcard Controller inside TI Calypso/Iota */
/* (C) 2010 by Philipp Fabian Benedikt Maier <philipp-maier@runningserver.com>
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
*
* All Rights Reserved
*
@@ -20,34 +21,76 @@
*
*/
+/* Uncomment to debug sim */
+/* #define DEBUG */
+
#include <stdint.h>
#include <stdio.h>
#include <debug.h>
#include <memory.h>
+#include <string.h>
+#include <delay.h>
+#include <osmocom/core/msgb.h>
+#include <layer1/l23_api.h>
#include <abb/twl3025.h>
#include <calypso/sim.h>
#include <calypso/irq.h>
-static int sim_rx_character_count = 0; /* How many bytes have been received by calypso_sim_receive() */
-static int sim_tx_character_count = 0; /* How many bytes have been transmitted by calypso_sim_transmit() */
-static int sim_tx_character_length = 0; /* How many bytes have to be transmitted by calypso_sim_transmit() */
-static uint8_t *rx_buffer = 0; /* RX-Buffer that is issued by calypso_sim_receive() */
-static uint8_t *tx_buffer = 0; /* TX-Buffer that is issued by calypso_sim_transmit() */
-volatile static int rxDoneFlag = 0; /* Used for rx synchronization instead of a semaphore in calypso_sim_receive() */
-volatile static int txDoneFlag = 0; /* Used for rx synchronization instead of a semaphore in calypso_sim_transmit() */
+#include <l1ctl_proto.h>
+
+#define SIM_CLASS 0xA0
+ /* Class that contains the following instructions */
+#define SIM_GET_RESPONSE 0xC0
+ /* Get the response of a command from the card */
+#define SIM_READ_BINARY 0xB0 /* Read file in binary mode */
+#define SIM_READ_RECORD 0xB2 /* Read record in binary mode */
+
+enum {
+ SIM_STATE_IDLE,
+ SIM_STATE_TX_HEADER,
+ SIM_STATE_RX_STATUS,
+ SIM_STATE_RX_ACK,
+ SIM_STATE_RX_ACK_DATA,
+ SIM_STATE_TX_DATA,
+};
+
+#define L3_MSG_HEAD 4
+
+static uint8_t sim_data[256]; /* buffer for SIM command */
+static volatile uint16_t sim_len = 0; /* lenght of data in sim_data[] */
+static volatile uint8_t sim_state = SIM_STATE_IDLE;
+ /* current state of SIM process */
+static volatile uint8_t sim_ignore_waiting_char = 0;
+ /* signal ignoring of NULL procedure byte */
+static volatile int sim_rx_character_count = 0;
+ /* How many bytes have been received by calypso_sim_receive() */
+static volatile int sim_rx_max_character_count = 0;
+ /* How many bytes have been received by calypso_sim_receive() */
+static volatile int sim_tx_character_count = 0;
+ /* How many bytes have been transmitted by calypso_sim_transmit() */
+static volatile int sim_tx_character_length = 0;
+ /* How many bytes have to be transmitted by calypso_sim_transmit() */
+static uint8_t *rx_buffer = 0;
+ /* RX-Buffer that is issued by calypso_sim_receive() */
+static uint8_t *tx_buffer = 0;
+ /* TX-Buffer that is issued by calypso_sim_transmit() */
+static volatile int rxDoneFlag = 0;
+ /* Used for rx synchronization instead of a semaphore in calypso_sim_receive() */
+static volatile int txDoneFlag = 0;
+ /* Used for rx synchronization instead of a semaphore in calypso_sim_transmit() */
/* Display Register dump */
void calypso_sim_regdump(void)
{
-#if (SIM_DEBUG == 1)
+#ifdef DEBUG
unsigned int regVal;
+#define SIM_DEBUG_OUTPUTDELAY 200
- puts("\n\n\n");
- puts("====================== CALYPSO SIM REGISTER DUMP =====================\n");
- puts("Reg_sim_cmd register (R/W) - FFFE:0000\n");
-
+ puts("\n\n\n");
+ puts("====================== CALYPSO SIM REGISTER DUMP =====================\n");
+ puts("Reg_sim_cmd register (R/W) - FFFE:0000\n");
regVal = readw(REG_SIM_CMD);
printf(" |-REG_SIM_CMD = %04x\n", readw(REG_SIM_CMD));
@@ -149,25 +192,25 @@ void calypso_sim_regdump(void)
else
puts(" | |-REG_SIM_CONF1_CONFSCLKDIV = 0 ==> SIM clock frequency is 13/4 Mhz.\n");
delay_ms(SIM_DEBUG_OUTPUTDELAY);
-
+
if(regVal & REG_SIM_CONF1_CONFSCLKLEV)
puts(" | |-REG_SIM_CONF1_CONFSCLKLEV = 1 ==> SIM clock idle level is high.\n");
else
puts(" | |-REG_SIM_CONF1_CONFSCLKLEV = 0 ==> SIM clock idle level is low.\n");
delay_ms(SIM_DEBUG_OUTPUTDELAY);
-
+
if(regVal & REG_SIM_CONF1_CONFETUPERIOD)
puts(" | |-REG_SIM_CONF1_CONFETUPERIOD = 1 ==> ETU period is 512/8*1/Fsclk.\n");
else
puts(" | |-REG_SIM_CONF1_CONFETUPERIOD = 0 ==> ETU period is 372/8*1/Fsclk.\n");
delay_ms(SIM_DEBUG_OUTPUTDELAY);
-
+
if(regVal & REG_SIM_CONF1_CONFBYPASS)
puts(" | |-REG_SIM_CONF1_CONFBYPASS = 1 ==> Hardware timers and start and stop sequences are bypassed.\n");
else
puts(" | |-REG_SIM_CONF1_CONFBYPASS = 0 ==> Hardware timers and start and stop sequences are normal.\n");
delay_ms(SIM_DEBUG_OUTPUTDELAY);
-
+
if(regVal & REG_SIM_CONF1_CONFSVCCLEV)
puts(" | |-REG_SIM_CONF1_CONFSVCCLEV = 1 ==> SVCC Level is high (Only valid when CONFBYPASS = 1).\n");
else
@@ -301,122 +344,32 @@ void calypso_sim_regdump(void)
return;
}
-/* Apply power to the simcard (use nullpointer to ignore atr) */
-int calypso_sim_powerup(uint8_t *atr)
-{
- /* Enable level shifters and voltage regulator */
- twl3025_reg_write(VRPCSIM, VRPCSIM_SIMLEN | VRPCSIM_RSIMEN | VRPCSIM_SIMSEL);
-#if (SIM_DEBUG == 1)
- puts(" * Power enabled!\n");
-#endif
- delay_ms(SIM_OPERATION_DELAY);
-
- /* Enable clock */
- writew(REG_SIM_CMD_MODULE_CLK_EN | REG_SIM_CMD_CMDSTART, REG_SIM_CMD);
-#if (SIM_DEBUG == 1)
- puts(" * Clock enabled!\n");
-#endif
- delay_ms(SIM_OPERATION_DELAY);
-
- /* Release reset */
- writew(readw(REG_SIM_CONF1) | REG_SIM_CONF1_CONFBYPASS | REG_SIM_CONF1_CONFSRSTLEV | REG_SIM_CONF1_CONFSVCCLEV, REG_SIM_CONF1);
-#if (SIM_DEBUG == 1)
- puts(" * Reset released!\n");
-#endif
-
- /* Catch ATR */
- if(atr != 0)
- return calypso_sim_receive(atr);
- else
- return 0;
-}
-
-
-/* Powerdown simcard */
-void calypso_sim_powerdown(void)
-{
- writew(readw(REG_SIM_CONF1) & ~REG_SIM_CONF1_CONFBYPASS, REG_SIM_CONF1);
-#if (SIM_DEBUG == 1)
- puts(" * Reset pulled down!\n");
-#endif
- delay_ms(SIM_OPERATION_DELAY);
-
- writew(REG_SIM_CMD_MODULE_CLK_EN | REG_SIM_CMD_CMDSTOP, REG_SIM_CMD);
-#if (SIM_DEBUG == 1)
- puts(" * Clock disabled!\n");
-#endif
- delay_ms(SIM_OPERATION_DELAY);
-
- writew(0, REG_SIM_CMD);
-#if (SIM_DEBUG == 1)
- puts(" * Module disabled!\n");
-#endif
- delay_ms(SIM_OPERATION_DELAY);
-
- /* Disable level shifters and voltage regulator */
- twl3025_reg_write(VRPCSIM, 0);
-#if (SIM_DEBUG == 1)
- puts(" * Power disabled!\n");
-#endif
- delay_ms(SIM_OPERATION_DELAY);
-
- return;
-}
-
-/* reset the simcard (see note 1) */
-int calypso_sim_reset(uint8_t *atr)
-{
-
- /* Pull reset down */
- writew(readw(REG_SIM_CONF1) & ~REG_SIM_CONF1_CONFSRSTLEV , REG_SIM_CONF1);
-#if (SIM_DEBUG == 1)
- puts(" * Reset pulled down!\n");
-#endif
-
- delay_ms(SIM_OPERATION_DELAY);
-
- /* Pull reset down */
- writew(readw(REG_SIM_CONF1) | REG_SIM_CONF1_CONFSRSTLEV , REG_SIM_CONF1);
-#if (SIM_DEBUG == 1)
- puts(" * Reset released!\n");
-#endif
-
- /* Catch ATR */
- if(atr != 0)
- return calypso_sim_receive(atr);
- else
- return 0;
-}
-
/* Receive raw data through the sim interface */
-int calypso_sim_receive(uint8_t *data)
+int calypso_sim_receive(uint8_t *data, uint8_t len)
{
+ printd("Triggering SIM reception\n");
+
/* Prepare buffers and flags */
rx_buffer = data;
sim_rx_character_count = 0;
rxDoneFlag = 0;
+ sim_rx_max_character_count = len;
/* Switch I/O direction to input */
writew(readw(REG_SIM_CONF1) & ~REG_SIM_CONF1_CONFTXRX, REG_SIM_CONF1);
/* Unmask the interrupts that are needed to perform this action */
- writew(~(REG_SIM_MASKIT_MASK_SIM_RX | REG_SIM_MASKIT_MASK_SIM_WT), REG_SIM_MASKIT);
-
- /* Wait till rxDoneFlag is set */
- while(rxDoneFlag == 0);
+ writew(~(REG_SIM_MASKIT_MASK_SIM_RX | REG_SIM_MASKIT_MASK_SIM_WT),
+ REG_SIM_MASKIT);
- /* Disable all interrupt driven functions by masking all interrupts */
- writew(0xFF, REG_SIM_MASKIT);
-
- /* Hand back the number of bytes received */
- return sim_rx_character_count;
-
- return;
+ return 0;
}
/* Transmit raw data through the sim interface */
int calypso_sim_transmit(uint8_t *data, int length)
{
+ printd("Triggering SIM transmission\n");
+
/* Prepare buffers and flags */
tx_buffer = data;
sim_tx_character_count = 0;
@@ -434,12 +387,6 @@ int calypso_sim_transmit(uint8_t *data, int length)
tx_buffer++;
sim_tx_character_count++;
- /* Wait till rxDoneFlag is set */
- while(txDoneFlag == 0);
-
- /* Disable all interrupt driven functions by masking all interrupts */
- writew(0xFF, REG_SIM_MASKIT);
-
return 0;
}
@@ -451,290 +398,344 @@ void sim_irq_handler(enum irq_nr irq)
/* Display interrupt information */
-#if (SIM_DEBUG == 1)
- puts("SIM-ISR: Interrupt caught: ");
-#endif
- if(regVal & REG_SIM_IT_SIM_NATR)
- {
-#if (SIM_DEBUG == 1)
- puts(" No answer to reset!\n");
-#endif
+ printd("SIM-ISR: ");
+
+ if(regVal & REG_SIM_IT_SIM_NATR) {
+ printd(" No answer to reset!\n");
}
- /* Used by: calypso_sim_receive() to determine when the transmission is over */
- if(regVal & REG_SIM_IT_SIM_WT)
- {
-#if (SIM_DEBUG == 1)
- puts(" Character underflow!\n");
-#endif
+ /* Used by: calypso_sim_receive() to determine when the transmission
+ * is over
+ */
+ if(regVal & REG_SIM_IT_SIM_WT) {
+ printd(" Character underflow!\n");
rxDoneFlag = 1;
+
}
- if(regVal & REG_SIM_IT_SIM_OV)
- {
-#if (SIM_DEBUG == 1)
- puts(" Receive overflow!\n");
-#endif
+ if(regVal & REG_SIM_IT_SIM_OV) {
+ printd(" Receive overflow!\n");
}
/* Used by: calypso_sim_transmit() to transmit the data */
- if(regVal & REG_SIM_IT_SIM_TX)
- {
-#if (SIM_DEBUG == 1)
- puts(" Waiting for character to transmit...\n");
-#endif
- if(sim_tx_character_count >= sim_tx_character_length)
+ if(regVal & REG_SIM_IT_SIM_TX) {
+ printd(" Waiting for transmit...\n");
+ if(sim_tx_character_count >= sim_tx_character_length) {
txDoneFlag = 1;
- else
- {
+ } else {
writew(*tx_buffer,REG_SIM_DTX);
tx_buffer++;
sim_tx_character_count++;
+
+ /* its essential to immediately switch to RX after TX
+ * is done
+ */
+ if(sim_tx_character_count >= sim_tx_character_length) {
+ /* TODO: set a proper delay here, 4 is to
+ long if not debugging and no delay is too
+ short */
+// delay_ms(1);
+ /* Switch I/O direction to input */
+ writew(readw(REG_SIM_CONF1) &
+ ~REG_SIM_CONF1_CONFTXRX, REG_SIM_CONF1);
+ }
}
}
/* Used by: calypso_sim_receive() to receive the incoming data */
- if(regVal & REG_SIM_IT_SIM_RX)
- {
-#if (SIM_DEBUG == 1)
- puts(" Waiting characters to be read...\n");
-#endif
- /* Increment character count - this is what calypso_sim_receive() hands back */
+ if(regVal & REG_SIM_IT_SIM_RX) {
+ uint8_t ch = (uint8_t) (readw(REG_SIM_DRX) & 0xFF);
+
+ /* ignore NULL procedure byte */
+ if(ch == 0x60 && sim_ignore_waiting_char) {
+ printd(" 0x60 received...\n");
+ return;
+ }
+
+ printd(" Waiting for read (%02X)...\n", ch);
+
+ /* Increment character count - this is what
+ * calypso_sim_receive() hands back
+ */
sim_rx_character_count++;
/* Read byte from rx-fifo and write it to the issued buffer */
- *rx_buffer = (uint8_t) (readw(REG_SIM_DRX) & 0xFF);
+ *rx_buffer = ch;
rx_buffer++;
+
+ /* to maximise SIM access speed, stop waiting after
+ all the expected characters have been received. */
+ if (sim_rx_max_character_count
+ && sim_rx_character_count >= sim_rx_max_character_count) {
+ printd(" Max characters received!\n");
+ rxDoneFlag = 1;
+ }
}
}
-/* Transceive T0 Apdu to sim acording to GSM 11.11 Page 34 */
-int calypso_sim_transceive(uint8_t cla, /* Class (in GSM context mostly 0xA0 */
- uint8_t ins, /* Instruction */
- uint8_t p1, /* First parameter */
- uint8_t p2, /* Second parameter */
- uint8_t p3le, /* Length of the data that should be transceived */
- uint8_t *data, /* Data payload */
- uint8_t *status, /* Status word (2 byte array, see note 1) */
- uint8_t mode) /* Mode of operation: 1=GET, 0=PUT */
-
- /* Note 1: You can use a null-pointer (0) if you are not interested in
- the status word */
+/* simm command from layer 23 */
+void sim_apdu(uint16_t len, uint8_t *data)
{
- uint8_t transmissionBuffer[256];
- uint8_t numberOfReceivedBytes;
-
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: Transceiving APDU-Header: (%02x %02x %02x %02x %02x)\n",cla,ins,p1,p2,p3le);
-#endif
+ if (sim_state != SIM_STATE_IDLE) {
+ puts("Sim reader currently busy...\n");
+ return;
+ }
+ memcpy(sim_data, data, len);
+ sim_len = len;
+}
- /* Transmit APDU header */
- memset(transmissionBuffer,0,sizeof(transmissionBuffer));
- transmissionBuffer[0] = cla;
- transmissionBuffer[1] = ins;
- transmissionBuffer[2] = p1;
- transmissionBuffer[3] = p2;
- transmissionBuffer[4] = p3le;
- calypso_sim_transmit(transmissionBuffer,5);
-
- /* Case 1: No input, No Output */
- if(p3le == 0)
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: Case 1: No input, No Output (See also GSM 11.11 Page 34)\n");
-#endif
- numberOfReceivedBytes = calypso_sim_receive(transmissionBuffer);
-
- if(numberOfReceivedBytes == 2)
- {
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: Status-word received: %02x %02x\n", transmissionBuffer[0], transmissionBuffer[1]);
-#endif
- /* Hand back status word */
- if(status != 0)
- {
- status[0] = transmissionBuffer[0];
- status[1] = transmissionBuffer[1];
- }
-
- return 0;
- }
+/* handling sim events */
+void sim_handler(void)
+{
+ static struct msgb *msg;
+ struct l1ctl_hdr *l1h;
+ static uint8_t mode;
+ static uint8_t *response;
+ static uint16_t length;
+
+ switch (sim_state) {
+ case SIM_STATE_IDLE:
+ if (!sim_len)
+ break; /* wait for SIM command */
+ /* check if instructions expects a response */
+ if (/* GET RESPONSE needs SIM_APDU_GET */
+ (sim_len == 5 && sim_data[0] == SIM_CLASS &&
+ sim_data[1] == SIM_GET_RESPONSE && sim_data[2] == 0x00 &&
+ sim_data[3] == 0x00) ||
+ /* READ BINARY/RECORD needs SIM_APDU_GET */
+ (sim_len >= 5 && sim_data[0] == SIM_CLASS &&
+ (sim_data[1] == SIM_READ_BINARY ||
+ sim_data[1] == SIM_READ_RECORD)))
+ mode = SIM_APDU_GET;
else
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error -- aborting!\n");
-#endif
- return -1;
+ mode = SIM_APDU_PUT;
+
+ length = sim_data[4];
+
+ /* allocate space for expected response */
+ msg = msgb_alloc_headroom(256, L3_MSG_HEAD
+ + sizeof(struct l1ctl_hdr), "l1ctl1");
+ response = msgb_put(msg, length + 2 + 1);
+
+ sim_state = SIM_STATE_TX_HEADER;
+
+ /* send APDU header */
+ calypso_sim_transmit(sim_data, 5);
+ break;
+ case SIM_STATE_TX_HEADER:
+ if (!txDoneFlag)
+ break; /* wait until header is transmitted */
+ /* Disable all interrupt driven functions */
+ writew(0xFF, REG_SIM_MASKIT);
+ /* Case 1: No input, No Output */
+ if (length == 0) {
+ sim_state = SIM_STATE_RX_STATUS;
+ calypso_sim_receive(response + 1, 2);
+ break;
+ }
+ /* Case 2: No input / Output of known length */
+ if (mode == SIM_APDU_PUT) {
+ sim_state = SIM_STATE_RX_ACK;
+ calypso_sim_receive(response, 1);
+ break;
+ /* Case 4: Input / No output */
+ } else {
+ sim_state = SIM_STATE_RX_ACK_DATA;
+ calypso_sim_receive(response, length + 1 + 2);
+ }
+ break;
+ case SIM_STATE_RX_STATUS:
+ if (!rxDoneFlag)
+ break; /* wait until data is received */
+ /* Disable all interrupt driven functions */
+ writew(0xFF, REG_SIM_MASKIT);
+ /* disable special ignore case */
+ sim_ignore_waiting_char = 0;
+ /* wrong number of bytes received */
+ if (sim_rx_character_count != 2) {
+ puts("SIM: Failed to read status\n");
+ goto error;
+ }
+ msgb_pull(msg, length + 1); /* pull up to status info */
+ goto queue;
+ case SIM_STATE_RX_ACK:
+ if (!rxDoneFlag)
+ break; /* wait until data is received */
+ /* Disable all interrupt driven functions */
+ writew(0xFF, REG_SIM_MASKIT);
+ /* error received */
+ if (sim_rx_character_count == 2) {
+ puts("SIM: command failed\n");
+ msgb_pull(msg, msg->len - 2);
+ msg->data[0] = response[0];
+ msg->data[1] = response[1];
+ goto queue;
+ }
+ /* wrong number of bytes received */
+ if (sim_rx_character_count != 1) {
+ puts("SIM: ACK read failed\n");
+ goto error;
+ }
+ if (response[0] != sim_data[1]) {
+ puts("SIM: ACK does not match request\n");
+ goto error;
+ }
+ sim_state = SIM_STATE_TX_DATA;
+ calypso_sim_transmit(sim_data + 5, length);
+ break;
+ case SIM_STATE_TX_DATA:
+ if (!txDoneFlag)
+ break; /* wait until data is transmitted */
+ /* Disable all interrupt driven functions */
+ writew(0xFF, REG_SIM_MASKIT);
+ /* Ignore waiting char for RUN GSM ALGORITHM */
+ /* TODO: implement proper handling of the "Procedure Bytes"
+ than this is no longer needed */
+ if(sim_data[1] == 0x88)
+ sim_ignore_waiting_char = 1;
+ sim_state = SIM_STATE_RX_STATUS;
+ calypso_sim_receive(response + length + 1, 2);
+ break;
+ case SIM_STATE_RX_ACK_DATA:
+ if (!rxDoneFlag)
+ break; /* wait until data is received */
+ /* Disable all interrupt driven functions */
+ writew(0xFF, REG_SIM_MASKIT);
+ /* error received */
+ if (sim_rx_character_count == 2) {
+ puts("SIM: command failed\n");
+ msgb_pull(msg, msg->len - 2);
+ msg->data[0] = response[0];
+ msg->data[1] = response[1];
+ goto queue;
+ }
+ /* wrong number of bytes received */
+ if (sim_rx_character_count != length + 1 + 2) {
+ puts("SIM: Failed to read data\n");
+ goto error;
}
+ msgb_pull(msg, 1); /* pull ACK byte */
+ goto queue;
}
- /* Case 2: No input / Output of known length */
- else if(mode == SIM_APDU_PUT)
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: Case 2: No input / Output of known length (See also GSM 11.11 Page 34)\n");
-#endif
+ return;
- numberOfReceivedBytes = calypso_sim_receive(transmissionBuffer);
+error:
+ msgb_pull(msg, msg->len - 2);
+ msg->data[0] = 0;
+ msg->data[1] = 0;
+queue:
+ printf("SIM Response (%d): %s\n", msg->len,
+ osmo_hexdump(msg->data, msg->len));
+ l1h = (struct l1ctl_hdr *) msgb_push(msg, sizeof(*l1h));
+ l1h->msg_type = L1CTL_SIM_CONF;
+ l1h->flags = 0;
+ msg->l1h = (uint8_t *)l1h;
+ l1_queue_for_l2(msg);
+ /* go IDLE */
+ sim_state = SIM_STATE_IDLE;
+ sim_len = 0;
- /* Error situation: The card has aborted, sends no data but a status word */
- if(numberOfReceivedBytes == 2)
- {
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: Status-word received (ERROR): %02x %02x\n", transmissionBuffer[0], transmissionBuffer[1]);
-#endif
- /* Hand back status word */
- if(status != 0)
- {
- status[0] = transmissionBuffer[0];
- status[1] = transmissionBuffer[1];
- }
-
- return 0;
- }
- /* Acknoledge byte received */
- else if(numberOfReceivedBytes == 1)
- {
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: ACK received: %02x\n", transmissionBuffer[0]);
-#endif
- /* Check if ACK is valid */
- if(transmissionBuffer[0] != ins)
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error: Invalid ACK byte -- aborting!\n");
-#endif
- return -1;
- }
-
- /* Transmit body */
- calypso_sim_transmit(data,p3le);
-
- /* Receive status word */
- numberOfReceivedBytes = calypso_sim_receive(transmissionBuffer);
-
- /* Check status word */
- if(numberOfReceivedBytes == 2)
- {
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: Status-word received: %02x %02x\n", transmissionBuffer[0], transmissionBuffer[1]);
-#endif
+ return;
+}
- /* Hand back status word */
- if(status != 0)
- {
- status[0] = transmissionBuffer[0];
- status[1] = transmissionBuffer[1];
- }
+/* Initialize simcard interface */
+void calypso_sim_init(void)
+{
+ /* Register IRQ handler and turn interrupts on */
+ printd("SIM: Registering interrupt handler for simcard-interface\n");
- return 0;
- }
- else
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error: Missing or invalid status word -- aborting!\n");
-#endif
- return -1;
- }
- }
- else
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error: Missing ACK byte -- aborting!\n");
-#endif
- return -1;
- }
- }
+ irq_register_handler(IRQ_SIMCARD, &sim_irq_handler);
- /* Case 4: Input / No output */
- else if(mode == SIM_APDU_GET)
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: Case 4: Input / No output (See also GSM 11.11 Page 34)\n");
+#if 1
+ irq_config(IRQ_SIMCARD, 0, 0, 0xff);
+#else
+ irq_config(IRQ_SIMCARD, 0, 0, 1);
#endif
- numberOfReceivedBytes = calypso_sim_receive(data);
-
- /* Error situation: The card has aborted, sends no data but a status word */
- if(numberOfReceivedBytes == 2)
- {
+ irq_enable(IRQ_SIMCARD);
+}
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: Status-word received (ERROR): %02x %02x\n", data[0], data[1]);
+/* Apply power to the simcard (use nullpointer to ignore atr) */
+int calypso_sim_powerup(uint8_t *atr)
+{
+ /* Enable level shifters and voltage regulator */
+#if 1 // 2.9V
+ twl3025_reg_write(VRPCSIM, VRPCSIM_SIMLEN | VRPCSIM_RSIMEN
+ | VRPCSIM_SIMSEL);
+#else // 1.8V
+ twl3025_reg_write(VRPCSIM, VRPCSIM_SIMLEN | VRPCSIM_RSIMEN);
#endif
- /* Hand back status word */
- if(status != 0)
- {
- status[0] = data[0];
- status[1] = data[1];
- }
-
- return 0;
- }
+ printd(" * Power enabled!\n");
+ delay_ms(SIM_OPERATION_DELAY);
- /* Data correctly received */
- else if(numberOfReceivedBytes == p3le + 1 + 2)
- {
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: ACK received: %02x\n", data[0]);
-#endif
- /* Check if ACK is valid */
- if(data[0] != ins)
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error: Invalid ACK byte -- aborting!\n");
-#endif
- return -1;
- }
+ /* Enable clock */
+ writew(REG_SIM_CMD_MODULE_CLK_EN | REG_SIM_CMD_CMDSTART, REG_SIM_CMD);
+ printd(" * Clock enabled!\n");
+ delay_ms(SIM_OPERATION_DELAY);
-#if (SIM_DEBUG == 1)
- printf("SIM-T0: Status-word received: %02x %02x\n", data[p3le + 1], data[p3le + 2]);
-#endif
- /* Hand back status word */
- if(status != 0)
- {
- status[0] = data[p3le + 1];
- status[1] = data[p3le + 2];
- }
-
- /* Move data one position left to cut away the ACK-Byte */
- memcpy(data,data+1,p3le);
-
- return 0;
- }
- else
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error: Incorrect or missing answer -- aborting!\n");
-#endif
- return -1;
- }
- }
+ /* Release reset */
+ writew(readw(REG_SIM_CONF1) | REG_SIM_CONF1_CONFBYPASS
+ | REG_SIM_CONF1_CONFSRSTLEV
+ | REG_SIM_CONF1_CONFSVCCLEV, REG_SIM_CONF1);
+ printd(" * Reset released!\n");
- /* Should not happen, if it happens then the programmer has submitted invalid parameters! */
- else
- {
-#if (SIM_DEBUG == 1)
- puts("SIM-T0: T0 Protocol error: Invalid case (program bug!) -- aborting!\n");
-#endif
+ /* Catch ATR */
+ if(atr != 0) {
+ calypso_sim_receive(atr, 0);
+ while (!rxDoneFlag)
+ ;
}
- /* Note: The other cases are not implemented because they are already covered
- by the CASE 1,2 and 4. */
-
return 0;
}
-/* Initialize simcard interface */
-void calypso_sim_init(void)
+/* Powerdown simcard */
+void calypso_sim_powerdown(void)
{
- /* Register IRQ handler and turn interrupts on */
-#if (SIM_DEBUG == 1)
- puts("SIM: Registering interrupt handler for simcard-interface\n");
-#endif
- irq_register_handler(IRQ_SIMCARD, &sim_irq_handler);
- irq_config(IRQ_SIMCARD, 0, 0, 0xff);
- irq_enable(IRQ_SIMCARD);
+ writew(readw(REG_SIM_CONF1) & ~REG_SIM_CONF1_CONFBYPASS, REG_SIM_CONF1);
+ printd(" * Reset pulled down!\n");
+ delay_ms(SIM_OPERATION_DELAY);
+
+ writew(REG_SIM_CMD_MODULE_CLK_EN | REG_SIM_CMD_CMDSTOP, REG_SIM_CMD);
+ printd(" * Clock disabled!\n");
+ delay_ms(SIM_OPERATION_DELAY);
+
+ writew(0, REG_SIM_CMD);
+ printd(" * Module disabled!\n");
+ delay_ms(SIM_OPERATION_DELAY);
+
+ /* Disable level shifters and voltage regulator */
+ twl3025_reg_write(VRPCSIM, 0);
+ printd(" * Power disabled!\n");
+ delay_ms(SIM_OPERATION_DELAY);
+
+ return;
+}
+
+/* reset the simcard (see note 1) */
+int calypso_sim_reset(uint8_t *atr)
+{
+
+ /* Pull reset down */
+ writew(readw(REG_SIM_CONF1) & ~REG_SIM_CONF1_CONFSRSTLEV,
+ REG_SIM_CONF1);
+ printd(" * Reset pulled down!\n");
+
+ delay_ms(SIM_OPERATION_DELAY);
+
+ /* Pull reset down */
+ writew(readw(REG_SIM_CONF1) | REG_SIM_CONF1_CONFSRSTLEV, REG_SIM_CONF1);
+ printd(" * Reset released!\n");
+
+ /* Catch ATR */
+ if(atr != 0) {
+ calypso_sim_receive(atr, 0);
+ while (!rxDoneFlag)
+ ;
+ }
+
+ return 0;
}
diff --git a/Src/osmolib/src/target/firmware/comm/msgb.c b/Src/osmolib/src/target/firmware/comm/msgb.c
index 4215d24..3524ba5 100644
--- a/Src/osmolib/src/target/firmware/comm/msgb.c
+++ b/Src/osmolib/src/target/firmware/comm/msgb.c
@@ -26,6 +26,7 @@
#include <debug.h>
#include <delay.h>
+#include <console.h>
#include <osmocom/core/msgb.h>
diff --git a/Src/osmolib/src/target/firmware/comm/timer.c b/Src/osmolib/src/target/firmware/comm/timer.c
index 6a649ae..ce4f06d 100644
--- a/Src/osmolib/src/target/firmware/comm/timer.c
+++ b/Src/osmolib/src/target/firmware/comm/timer.c
@@ -33,22 +33,20 @@ static LLIST_HEAD(timer_list);
unsigned long volatile jiffies;
-#define TIMER_HZ 100
-
#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(b) - (long)(a) < 0))
#define time_before(a,b) time_after(b,a)
-void add_timer(struct osmo_timer_list *timer)
+void osmo_timer_add(struct osmo_timer_list *timer)
{
struct osmo_timer_list *list_timer;
/* TODO: Optimize and remember the closest item... */
timer->active = 1;
- /* this might be called from within update_timers */
+ /* this might be called from within osmo_timers_update */
llist_for_each_entry(list_timer, &timer_list, entry)
if (timer == list_timer)
return;
@@ -57,13 +55,13 @@ void add_timer(struct osmo_timer_list *timer)
llist_add(&timer->entry, &timer_list);
}
-void schedule_timer(struct osmo_timer_list *timer, int milliseconds)
+void osmo_timer_schedule(struct osmo_timer_list *timer, int milliseconds)
{
- timer->expires = jiffies + ((milliseconds * TIMER_HZ) / 1000);
- add_timer(timer);
+ timer->expires = jiffies + ((milliseconds * HZ) / 1000);
+ osmo_timer_add(timer);
}
-void del_timer(struct osmo_timer_list *timer)
+void osmo_timer_del(struct osmo_timer_list *timer)
{
if (timer->in_list) {
timer->active = 0;
@@ -72,7 +70,7 @@ void del_timer(struct osmo_timer_list *timer)
}
}
-int timer_pending(struct osmo_timer_list *timer)
+int osmo_timer_pending(struct osmo_timer_list *timer)
{
return timer->active;
}
@@ -131,7 +129,7 @@ void prepare_timers()
/*
* fire all timers... and remove them
*/
-int update_timers(void)
+int osmo_timers_update(void)
{
struct osmo_timer_list *timer, *tmp;
int work = 0;
@@ -139,7 +137,7 @@ int update_timers(void)
/*
* The callbacks might mess with our list and in this case
* even llist_for_each_entry_safe is not safe to use. To allow
- * del_timer, add_timer, schedule_timer to be called from within
+ * osmo_timer_del, osmo_timer_add, osmo_timer_schedule to be called from within
* the callback we jump through some loops.
*
* First we set the handled flag of each active timer to zero,
@@ -149,7 +147,7 @@ int update_timers(void)
* is dispatched we will remove the non-active from the list.
*
* TODO: If this is a performance issue we can poison a global
- * variable in add_timer and del_timer and only then restart.
+ * variable in osmo_timer_add and osmo_timer_del and only then restart.
*/
llist_for_each_entry(timer, &timer_list, entry) {
timer->handled = 0;
@@ -169,14 +167,14 @@ restart:
llist_for_each_entry_safe(timer, tmp, &timer_list, entry) {
timer->handled = 0;
if (!timer->active) {
- del_timer(timer);
+ osmo_timer_del(timer);
}
}
return work;
}
-int timer_check(void)
+int osmo_timers_check(void)
{
struct osmo_timer_list *timer;
int i = 0;
@@ -200,10 +198,10 @@ void timer_init(void)
/* configure TIMER2 for our purpose */
hwtimer_enable(2, 1);
/* The timer runs at 13MHz / 32, i.e. 406.25kHz */
-#if (TIMER_HZ == 100)
+#if (HZ == 100)
hwtimer_load(2, 4062);
hwtimer_config(2, 0, 1);
-#elif (TIMER_HZ == 10)
+#elif (HZ == 10)
/* prescaler 4, 1015 ticks until expiry */
hwtimer_load(2, 1015);
hwtimer_config(2, 4, 1);
diff --git a/Src/osmolib/src/target/firmware/fb/4x6.c b/Src/osmolib/src/target/firmware/fb/4x6.c
new file mode 100644
index 0000000..2a35eba
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/4x6.c
@@ -0,0 +1,731 @@
+#include <fb/font.h>
+static const uint8_t font_4x6_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 4, 4, 1, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0x40, /* .#...... */
+ /*000c:*/ 0x40, /* .#...... */
+ /*000d:*/ 0x40, /* .#...... */
+ /*000e:*/ 0x00, /* ........ */
+ /*000f:*/ 0x40, /* .#...... */
+/* --- new character quotedbl (34) starting at offset 0x0010 --- */
+ /*0010:*/ 4, 4, 2, 0, 3, /* width and bbox (w,h,x,y) */
+ /*0015:*/ 0xa0, /* #.#..... */
+ /*0016:*/ 0xa0, /* #.#..... */
+/* --- new character numbersign (35) starting at offset 0x0017 --- */
+ /*0017:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*001c:*/ 0xa0, /* #.#..... */
+ /*001d:*/ 0xf0, /* ####.... */
+ /*001e:*/ 0xa0, /* #.#..... */
+ /*001f:*/ 0xf0, /* ####.... */
+ /*0020:*/ 0xa0, /* #.#..... */
+/* --- new character dollar (36) starting at offset 0x0021 --- */
+ /*0021:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0026:*/ 0x40, /* .#...... */
+ /*0027:*/ 0xe0, /* ###..... */
+ /*0028:*/ 0xc0, /* ##...... */
+ /*0029:*/ 0x20, /* ..#..... */
+ /*002a:*/ 0xe0, /* ###..... */
+ /*002b:*/ 0x40, /* .#...... */
+/* --- new character percent (37) starting at offset 0x002c --- */
+ /*002c:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0031:*/ 0x80, /* #....... */
+ /*0032:*/ 0x20, /* ..#..... */
+ /*0033:*/ 0x40, /* .#...... */
+ /*0034:*/ 0x80, /* #....... */
+ /*0035:*/ 0x20, /* ..#..... */
+/* --- new character ampersand (38) starting at offset 0x0036 --- */
+ /*0036:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*003b:*/ 0x40, /* .#...... */
+ /*003c:*/ 0xa0, /* #.#..... */
+ /*003d:*/ 0x40, /* .#...... */
+ /*003e:*/ 0xa0, /* #.#..... */
+ /*003f:*/ 0x50, /* .#.#.... */
+/* --- new character quotesingle (39) starting at offset 0x0040 --- */
+ /*0040:*/ 4, 4, 2, 0, 3, /* width and bbox (w,h,x,y) */
+ /*0045:*/ 0x40, /* .#...... */
+ /*0046:*/ 0x40, /* .#...... */
+/* --- new character parenleft (40) starting at offset 0x0047 --- */
+ /*0047:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*004c:*/ 0x20, /* ..#..... */
+ /*004d:*/ 0x40, /* .#...... */
+ /*004e:*/ 0x40, /* .#...... */
+ /*004f:*/ 0x40, /* .#...... */
+ /*0050:*/ 0x40, /* .#...... */
+ /*0051:*/ 0x20, /* ..#..... */
+/* --- new character parenright (41) starting at offset 0x0052 --- */
+ /*0052:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0057:*/ 0x80, /* #....... */
+ /*0058:*/ 0x40, /* .#...... */
+ /*0059:*/ 0x40, /* .#...... */
+ /*005a:*/ 0x40, /* .#...... */
+ /*005b:*/ 0x40, /* .#...... */
+ /*005c:*/ 0x80, /* #....... */
+/* --- new character asterisk (42) starting at offset 0x005d --- */
+ /*005d:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0062:*/ 0xa0, /* #.#..... */
+ /*0063:*/ 0x40, /* .#...... */
+ /*0064:*/ 0xe0, /* ###..... */
+ /*0065:*/ 0x40, /* .#...... */
+ /*0066:*/ 0xa0, /* #.#..... */
+/* --- new character plus (43) starting at offset 0x0067 --- */
+ /*0067:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*006c:*/ 0x40, /* .#...... */
+ /*006d:*/ 0x40, /* .#...... */
+ /*006e:*/ 0xe0, /* ###..... */
+ /*006f:*/ 0x40, /* .#...... */
+ /*0070:*/ 0x40, /* .#...... */
+/* --- new character comma (44) starting at offset 0x0071 --- */
+ /*0071:*/ 4, 4, 2, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0076:*/ 0x40, /* .#...... */
+ /*0077:*/ 0x80, /* #....... */
+/* --- new character hyphen (45) starting at offset 0x0078 --- */
+ /*0078:*/ 4, 4, 1, 0, 2, /* width and bbox (w,h,x,y) */
+ /*007d:*/ 0xe0, /* ###..... */
+/* --- new character period (46) starting at offset 0x007e --- */
+ /*007e:*/ 4, 4, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0083:*/ 0x40, /* .#...... */
+/* --- new character slash (47) starting at offset 0x0084 --- */
+ /*0084:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0089:*/ 0x20, /* ..#..... */
+ /*008a:*/ 0x20, /* ..#..... */
+ /*008b:*/ 0x40, /* .#...... */
+ /*008c:*/ 0x80, /* #....... */
+ /*008d:*/ 0x80, /* #....... */
+/* --- new character zero (48) starting at offset 0x008e --- */
+ /*008e:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0093:*/ 0x40, /* .#...... */
+ /*0094:*/ 0xa0, /* #.#..... */
+ /*0095:*/ 0xe0, /* ###..... */
+ /*0096:*/ 0xa0, /* #.#..... */
+ /*0097:*/ 0x40, /* .#...... */
+/* --- new character one (49) starting at offset 0x0098 --- */
+ /*0098:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*009d:*/ 0x40, /* .#...... */
+ /*009e:*/ 0xc0, /* ##...... */
+ /*009f:*/ 0x40, /* .#...... */
+ /*00a0:*/ 0x40, /* .#...... */
+ /*00a1:*/ 0xe0, /* ###..... */
+/* --- new character two (50) starting at offset 0x00a2 --- */
+ /*00a2:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00a7:*/ 0x40, /* .#...... */
+ /*00a8:*/ 0xa0, /* #.#..... */
+ /*00a9:*/ 0x20, /* ..#..... */
+ /*00aa:*/ 0x40, /* .#...... */
+ /*00ab:*/ 0xe0, /* ###..... */
+/* --- new character three (51) starting at offset 0x00ac --- */
+ /*00ac:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00b1:*/ 0xe0, /* ###..... */
+ /*00b2:*/ 0x20, /* ..#..... */
+ /*00b3:*/ 0x40, /* .#...... */
+ /*00b4:*/ 0x20, /* ..#..... */
+ /*00b5:*/ 0xc0, /* ##...... */
+/* --- new character four (52) starting at offset 0x00b6 --- */
+ /*00b6:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00bb:*/ 0xa0, /* #.#..... */
+ /*00bc:*/ 0xa0, /* #.#..... */
+ /*00bd:*/ 0xe0, /* ###..... */
+ /*00be:*/ 0x20, /* ..#..... */
+ /*00bf:*/ 0x20, /* ..#..... */
+/* --- new character five (53) starting at offset 0x00c0 --- */
+ /*00c0:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00c5:*/ 0xe0, /* ###..... */
+ /*00c6:*/ 0x80, /* #....... */
+ /*00c7:*/ 0xc0, /* ##...... */
+ /*00c8:*/ 0x20, /* ..#..... */
+ /*00c9:*/ 0xc0, /* ##...... */
+/* --- new character six (54) starting at offset 0x00ca --- */
+ /*00ca:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00cf:*/ 0x60, /* .##..... */
+ /*00d0:*/ 0x80, /* #....... */
+ /*00d1:*/ 0xc0, /* ##...... */
+ /*00d2:*/ 0xa0, /* #.#..... */
+ /*00d3:*/ 0x40, /* .#...... */
+/* --- new character seven (55) starting at offset 0x00d4 --- */
+ /*00d4:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00d9:*/ 0xe0, /* ###..... */
+ /*00da:*/ 0x20, /* ..#..... */
+ /*00db:*/ 0x40, /* .#...... */
+ /*00dc:*/ 0x80, /* #....... */
+ /*00dd:*/ 0x80, /* #....... */
+/* --- new character eight (56) starting at offset 0x00de --- */
+ /*00de:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00e3:*/ 0x60, /* .##..... */
+ /*00e4:*/ 0xa0, /* #.#..... */
+ /*00e5:*/ 0x40, /* .#...... */
+ /*00e6:*/ 0xa0, /* #.#..... */
+ /*00e7:*/ 0xc0, /* ##...... */
+/* --- new character nine (57) starting at offset 0x00e8 --- */
+ /*00e8:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00ed:*/ 0x40, /* .#...... */
+ /*00ee:*/ 0xa0, /* #.#..... */
+ /*00ef:*/ 0x60, /* .##..... */
+ /*00f0:*/ 0x20, /* ..#..... */
+ /*00f1:*/ 0xc0, /* ##...... */
+/* --- new character colon (58) starting at offset 0x00f2 --- */
+ /*00f2:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00f7:*/ 0x40, /* .#...... */
+ /*00f8:*/ 0x00, /* ........ */
+ /*00f9:*/ 0x00, /* ........ */
+ /*00fa:*/ 0x40, /* .#...... */
+/* --- new character semicolon (59) starting at offset 0x00fb --- */
+ /*00fb:*/ 4, 4, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0100:*/ 0x40, /* .#...... */
+ /*0101:*/ 0x00, /* ........ */
+ /*0102:*/ 0x00, /* ........ */
+ /*0103:*/ 0x40, /* .#...... */
+ /*0104:*/ 0x80, /* #....... */
+/* --- new character less (60) starting at offset 0x0105 --- */
+ /*0105:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*010a:*/ 0x20, /* ..#..... */
+ /*010b:*/ 0x40, /* .#...... */
+ /*010c:*/ 0x80, /* #....... */
+ /*010d:*/ 0x40, /* .#...... */
+ /*010e:*/ 0x20, /* ..#..... */
+/* --- new character equal (61) starting at offset 0x010f --- */
+ /*010f:*/ 4, 4, 3, 0, 1, /* width and bbox (w,h,x,y) */
+ /*0114:*/ 0xe0, /* ###..... */
+ /*0115:*/ 0x00, /* ........ */
+ /*0116:*/ 0xe0, /* ###..... */
+/* --- new character greater (62) starting at offset 0x0117 --- */
+ /*0117:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*011c:*/ 0x80, /* #....... */
+ /*011d:*/ 0x40, /* .#...... */
+ /*011e:*/ 0x20, /* ..#..... */
+ /*011f:*/ 0x40, /* .#...... */
+ /*0120:*/ 0x80, /* #....... */
+/* --- new character question (63) starting at offset 0x0121 --- */
+ /*0121:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0126:*/ 0xc0, /* ##...... */
+ /*0127:*/ 0x20, /* ..#..... */
+ /*0128:*/ 0x40, /* .#...... */
+ /*0129:*/ 0x00, /* ........ */
+ /*012a:*/ 0x40, /* .#...... */
+/* --- new character at (64) starting at offset 0x012b --- */
+ /*012b:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0130:*/ 0x60, /* .##..... */
+ /*0131:*/ 0xa0, /* #.#..... */
+ /*0132:*/ 0xa0, /* #.#..... */
+ /*0133:*/ 0x80, /* #....... */
+ /*0134:*/ 0x60, /* .##..... */
+/* --- new character A (65) starting at offset 0x0135 --- */
+ /*0135:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*013a:*/ 0x40, /* .#...... */
+ /*013b:*/ 0xa0, /* #.#..... */
+ /*013c:*/ 0xe0, /* ###..... */
+ /*013d:*/ 0xa0, /* #.#..... */
+ /*013e:*/ 0xa0, /* #.#..... */
+/* --- new character B (66) starting at offset 0x013f --- */
+ /*013f:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0144:*/ 0xc0, /* ##...... */
+ /*0145:*/ 0xa0, /* #.#..... */
+ /*0146:*/ 0xc0, /* ##...... */
+ /*0147:*/ 0xa0, /* #.#..... */
+ /*0148:*/ 0xc0, /* ##...... */
+/* --- new character C (67) starting at offset 0x0149 --- */
+ /*0149:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*014e:*/ 0x40, /* .#...... */
+ /*014f:*/ 0xa0, /* #.#..... */
+ /*0150:*/ 0x80, /* #....... */
+ /*0151:*/ 0xa0, /* #.#..... */
+ /*0152:*/ 0x40, /* .#...... */
+/* --- new character D (68) starting at offset 0x0153 --- */
+ /*0153:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0158:*/ 0xc0, /* ##...... */
+ /*0159:*/ 0xa0, /* #.#..... */
+ /*015a:*/ 0xa0, /* #.#..... */
+ /*015b:*/ 0xa0, /* #.#..... */
+ /*015c:*/ 0xc0, /* ##...... */
+/* --- new character E (69) starting at offset 0x015d --- */
+ /*015d:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0162:*/ 0xe0, /* ###..... */
+ /*0163:*/ 0x80, /* #....... */
+ /*0164:*/ 0xc0, /* ##...... */
+ /*0165:*/ 0x80, /* #....... */
+ /*0166:*/ 0xe0, /* ###..... */
+/* --- new character F (70) starting at offset 0x0167 --- */
+ /*0167:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*016c:*/ 0xe0, /* ###..... */
+ /*016d:*/ 0x80, /* #....... */
+ /*016e:*/ 0xc0, /* ##...... */
+ /*016f:*/ 0x80, /* #....... */
+ /*0170:*/ 0x80, /* #....... */
+/* --- new character G (71) starting at offset 0x0171 --- */
+ /*0171:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0176:*/ 0x60, /* .##..... */
+ /*0177:*/ 0x80, /* #....... */
+ /*0178:*/ 0xa0, /* #.#..... */
+ /*0179:*/ 0xa0, /* #.#..... */
+ /*017a:*/ 0x60, /* .##..... */
+/* --- new character H (72) starting at offset 0x017b --- */
+ /*017b:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0180:*/ 0xa0, /* #.#..... */
+ /*0181:*/ 0xa0, /* #.#..... */
+ /*0182:*/ 0xe0, /* ###..... */
+ /*0183:*/ 0xa0, /* #.#..... */
+ /*0184:*/ 0xa0, /* #.#..... */
+/* --- new character I (73) starting at offset 0x0185 --- */
+ /*0185:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*018a:*/ 0xe0, /* ###..... */
+ /*018b:*/ 0x40, /* .#...... */
+ /*018c:*/ 0x40, /* .#...... */
+ /*018d:*/ 0x40, /* .#...... */
+ /*018e:*/ 0xe0, /* ###..... */
+/* --- new character J (74) starting at offset 0x018f --- */
+ /*018f:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0194:*/ 0x20, /* ..#..... */
+ /*0195:*/ 0x20, /* ..#..... */
+ /*0196:*/ 0x20, /* ..#..... */
+ /*0197:*/ 0xa0, /* #.#..... */
+ /*0198:*/ 0x40, /* .#...... */
+/* --- new character K (75) starting at offset 0x0199 --- */
+ /*0199:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*019e:*/ 0xa0, /* #.#..... */
+ /*019f:*/ 0xa0, /* #.#..... */
+ /*01a0:*/ 0xc0, /* ##...... */
+ /*01a1:*/ 0xa0, /* #.#..... */
+ /*01a2:*/ 0xa0, /* #.#..... */
+/* --- new character L (76) starting at offset 0x01a3 --- */
+ /*01a3:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01a8:*/ 0x80, /* #....... */
+ /*01a9:*/ 0x80, /* #....... */
+ /*01aa:*/ 0x80, /* #....... */
+ /*01ab:*/ 0x80, /* #....... */
+ /*01ac:*/ 0xe0, /* ###..... */
+/* --- new character M (77) starting at offset 0x01ad --- */
+ /*01ad:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01b2:*/ 0xa0, /* #.#..... */
+ /*01b3:*/ 0xe0, /* ###..... */
+ /*01b4:*/ 0xe0, /* ###..... */
+ /*01b5:*/ 0xa0, /* #.#..... */
+ /*01b6:*/ 0xa0, /* #.#..... */
+/* --- new character N (78) starting at offset 0x01b7 --- */
+ /*01b7:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01bc:*/ 0x20, /* ..#..... */
+ /*01bd:*/ 0xa0, /* #.#..... */
+ /*01be:*/ 0xe0, /* ###..... */
+ /*01bf:*/ 0xa0, /* #.#..... */
+ /*01c0:*/ 0x80, /* #....... */
+/* --- new character O (79) starting at offset 0x01c1 --- */
+ /*01c1:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01c6:*/ 0x40, /* .#...... */
+ /*01c7:*/ 0xa0, /* #.#..... */
+ /*01c8:*/ 0xa0, /* #.#..... */
+ /*01c9:*/ 0xa0, /* #.#..... */
+ /*01ca:*/ 0x40, /* .#...... */
+/* --- new character P (80) starting at offset 0x01cb --- */
+ /*01cb:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01d0:*/ 0xc0, /* ##...... */
+ /*01d1:*/ 0xa0, /* #.#..... */
+ /*01d2:*/ 0xc0, /* ##...... */
+ /*01d3:*/ 0x80, /* #....... */
+ /*01d4:*/ 0x80, /* #....... */
+/* --- new character Q (81) starting at offset 0x01d5 --- */
+ /*01d5:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*01da:*/ 0x40, /* .#...... */
+ /*01db:*/ 0xa0, /* #.#..... */
+ /*01dc:*/ 0xa0, /* #.#..... */
+ /*01dd:*/ 0xa0, /* #.#..... */
+ /*01de:*/ 0x40, /* .#...... */
+ /*01df:*/ 0x20, /* ..#..... */
+/* --- new character R (82) starting at offset 0x01e0 --- */
+ /*01e0:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01e5:*/ 0xc0, /* ##...... */
+ /*01e6:*/ 0xa0, /* #.#..... */
+ /*01e7:*/ 0xc0, /* ##...... */
+ /*01e8:*/ 0xa0, /* #.#..... */
+ /*01e9:*/ 0xa0, /* #.#..... */
+/* --- new character S (83) starting at offset 0x01ea --- */
+ /*01ea:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01ef:*/ 0x60, /* .##..... */
+ /*01f0:*/ 0x80, /* #....... */
+ /*01f1:*/ 0x40, /* .#...... */
+ /*01f2:*/ 0x20, /* ..#..... */
+ /*01f3:*/ 0xc0, /* ##...... */
+/* --- new character T (84) starting at offset 0x01f4 --- */
+ /*01f4:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01f9:*/ 0xe0, /* ###..... */
+ /*01fa:*/ 0x40, /* .#...... */
+ /*01fb:*/ 0x40, /* .#...... */
+ /*01fc:*/ 0x40, /* .#...... */
+ /*01fd:*/ 0x40, /* .#...... */
+/* --- new character U (85) starting at offset 0x01fe --- */
+ /*01fe:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0203:*/ 0xa0, /* #.#..... */
+ /*0204:*/ 0xa0, /* #.#..... */
+ /*0205:*/ 0xa0, /* #.#..... */
+ /*0206:*/ 0xa0, /* #.#..... */
+ /*0207:*/ 0xe0, /* ###..... */
+/* --- new character V (86) starting at offset 0x0208 --- */
+ /*0208:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*020d:*/ 0xa0, /* #.#..... */
+ /*020e:*/ 0xa0, /* #.#..... */
+ /*020f:*/ 0xa0, /* #.#..... */
+ /*0210:*/ 0xe0, /* ###..... */
+ /*0211:*/ 0x40, /* .#...... */
+/* --- new character W (87) starting at offset 0x0212 --- */
+ /*0212:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0217:*/ 0xa0, /* #.#..... */
+ /*0218:*/ 0xa0, /* #.#..... */
+ /*0219:*/ 0xe0, /* ###..... */
+ /*021a:*/ 0xe0, /* ###..... */
+ /*021b:*/ 0xa0, /* #.#..... */
+/* --- new character X (88) starting at offset 0x021c --- */
+ /*021c:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0221:*/ 0xa0, /* #.#..... */
+ /*0222:*/ 0xa0, /* #.#..... */
+ /*0223:*/ 0x40, /* .#...... */
+ /*0224:*/ 0xa0, /* #.#..... */
+ /*0225:*/ 0xa0, /* #.#..... */
+/* --- new character Y (89) starting at offset 0x0226 --- */
+ /*0226:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*022b:*/ 0xa0, /* #.#..... */
+ /*022c:*/ 0xa0, /* #.#..... */
+ /*022d:*/ 0x40, /* .#...... */
+ /*022e:*/ 0x40, /* .#...... */
+ /*022f:*/ 0x40, /* .#...... */
+/* --- new character Z (90) starting at offset 0x0230 --- */
+ /*0230:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0235:*/ 0xe0, /* ###..... */
+ /*0236:*/ 0x20, /* ..#..... */
+ /*0237:*/ 0x40, /* .#...... */
+ /*0238:*/ 0x80, /* #....... */
+ /*0239:*/ 0xe0, /* ###..... */
+/* --- new character bracketleft (91) starting at offset 0x023a --- */
+ /*023a:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*023f:*/ 0x60, /* .##..... */
+ /*0240:*/ 0x40, /* .#...... */
+ /*0241:*/ 0x40, /* .#...... */
+ /*0242:*/ 0x40, /* .#...... */
+ /*0243:*/ 0x60, /* .##..... */
+/* --- new character backslash (92) starting at offset 0x0244 --- */
+ /*0244:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0249:*/ 0x80, /* #....... */
+ /*024a:*/ 0x80, /* #....... */
+ /*024b:*/ 0x40, /* .#...... */
+ /*024c:*/ 0x20, /* ..#..... */
+ /*024d:*/ 0x20, /* ..#..... */
+/* --- new character bracketright (93) starting at offset 0x024e --- */
+ /*024e:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0253:*/ 0xc0, /* ##...... */
+ /*0254:*/ 0x40, /* .#...... */
+ /*0255:*/ 0x40, /* .#...... */
+ /*0256:*/ 0x40, /* .#...... */
+ /*0257:*/ 0xc0, /* ##...... */
+/* --- new character asciicircum (94) starting at offset 0x0258 --- */
+ /*0258:*/ 4, 4, 2, 0, 3, /* width and bbox (w,h,x,y) */
+ /*025d:*/ 0x40, /* .#...... */
+ /*025e:*/ 0xa0, /* #.#..... */
+/* --- new character underscore (95) starting at offset 0x025f --- */
+ /*025f:*/ 4, 4, 1, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0264:*/ 0xe0, /* ###..... */
+/* --- new character grave (96) starting at offset 0x0265 --- */
+ /*0265:*/ 4, 4, 2, 0, 3, /* width and bbox (w,h,x,y) */
+ /*026a:*/ 0x40, /* .#...... */
+ /*026b:*/ 0x20, /* ..#..... */
+/* --- new character a (97) starting at offset 0x026c --- */
+ /*026c:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0271:*/ 0x60, /* .##..... */
+ /*0272:*/ 0xa0, /* #.#..... */
+ /*0273:*/ 0xa0, /* #.#..... */
+ /*0274:*/ 0x60, /* .##..... */
+/* --- new character b (98) starting at offset 0x0275 --- */
+ /*0275:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*027a:*/ 0x80, /* #....... */
+ /*027b:*/ 0xc0, /* ##...... */
+ /*027c:*/ 0xa0, /* #.#..... */
+ /*027d:*/ 0xa0, /* #.#..... */
+ /*027e:*/ 0xc0, /* ##...... */
+/* --- new character c (99) starting at offset 0x027f --- */
+ /*027f:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0284:*/ 0x60, /* .##..... */
+ /*0285:*/ 0x80, /* #....... */
+ /*0286:*/ 0x80, /* #....... */
+ /*0287:*/ 0x60, /* .##..... */
+/* --- new character d (100) starting at offset 0x0288 --- */
+ /*0288:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*028d:*/ 0x20, /* ..#..... */
+ /*028e:*/ 0x60, /* .##..... */
+ /*028f:*/ 0xa0, /* #.#..... */
+ /*0290:*/ 0xa0, /* #.#..... */
+ /*0291:*/ 0x60, /* .##..... */
+/* --- new character e (101) starting at offset 0x0292 --- */
+ /*0292:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0297:*/ 0x40, /* .#...... */
+ /*0298:*/ 0xa0, /* #.#..... */
+ /*0299:*/ 0xc0, /* ##...... */
+ /*029a:*/ 0x60, /* .##..... */
+/* --- new character f (102) starting at offset 0x029b --- */
+ /*029b:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02a0:*/ 0x20, /* ..#..... */
+ /*02a1:*/ 0x40, /* .#...... */
+ /*02a2:*/ 0xe0, /* ###..... */
+ /*02a3:*/ 0x40, /* .#...... */
+ /*02a4:*/ 0x40, /* .#...... */
+/* --- new character g (103) starting at offset 0x02a5 --- */
+ /*02a5:*/ 4, 4, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*02aa:*/ 0x60, /* .##..... */
+ /*02ab:*/ 0xa0, /* #.#..... */
+ /*02ac:*/ 0x60, /* .##..... */
+ /*02ad:*/ 0x20, /* ..#..... */
+ /*02ae:*/ 0xc0, /* ##...... */
+/* --- new character h (104) starting at offset 0x02af --- */
+ /*02af:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02b4:*/ 0x80, /* #....... */
+ /*02b5:*/ 0xc0, /* ##...... */
+ /*02b6:*/ 0xa0, /* #.#..... */
+ /*02b7:*/ 0xa0, /* #.#..... */
+ /*02b8:*/ 0xa0, /* #.#..... */
+/* --- new character i (105) starting at offset 0x02b9 --- */
+ /*02b9:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02be:*/ 0x40, /* .#...... */
+ /*02bf:*/ 0x00, /* ........ */
+ /*02c0:*/ 0xc0, /* ##...... */
+ /*02c1:*/ 0x40, /* .#...... */
+ /*02c2:*/ 0xe0, /* ###..... */
+/* --- new character j (106) starting at offset 0x02c3 --- */
+ /*02c3:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*02c8:*/ 0x20, /* ..#..... */
+ /*02c9:*/ 0x00, /* ........ */
+ /*02ca:*/ 0x20, /* ..#..... */
+ /*02cb:*/ 0x20, /* ..#..... */
+ /*02cc:*/ 0x20, /* ..#..... */
+ /*02cd:*/ 0xc0, /* ##...... */
+/* --- new character k (107) starting at offset 0x02ce --- */
+ /*02ce:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02d3:*/ 0x80, /* #....... */
+ /*02d4:*/ 0xa0, /* #.#..... */
+ /*02d5:*/ 0xc0, /* ##...... */
+ /*02d6:*/ 0xa0, /* #.#..... */
+ /*02d7:*/ 0xa0, /* #.#..... */
+/* --- new character l (108) starting at offset 0x02d8 --- */
+ /*02d8:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02dd:*/ 0xc0, /* ##...... */
+ /*02de:*/ 0x40, /* .#...... */
+ /*02df:*/ 0x40, /* .#...... */
+ /*02e0:*/ 0x40, /* .#...... */
+ /*02e1:*/ 0xe0, /* ###..... */
+/* --- new character m (109) starting at offset 0x02e2 --- */
+ /*02e2:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02e7:*/ 0xa0, /* #.#..... */
+ /*02e8:*/ 0xe0, /* ###..... */
+ /*02e9:*/ 0xa0, /* #.#..... */
+ /*02ea:*/ 0xa0, /* #.#..... */
+/* --- new character n (110) starting at offset 0x02eb --- */
+ /*02eb:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02f0:*/ 0xc0, /* ##...... */
+ /*02f1:*/ 0xa0, /* #.#..... */
+ /*02f2:*/ 0xa0, /* #.#..... */
+ /*02f3:*/ 0xa0, /* #.#..... */
+/* --- new character o (111) starting at offset 0x02f4 --- */
+ /*02f4:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02f9:*/ 0x40, /* .#...... */
+ /*02fa:*/ 0xa0, /* #.#..... */
+ /*02fb:*/ 0xa0, /* #.#..... */
+ /*02fc:*/ 0x40, /* .#...... */
+/* --- new character p (112) starting at offset 0x02fd --- */
+ /*02fd:*/ 4, 4, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0302:*/ 0xc0, /* ##...... */
+ /*0303:*/ 0xa0, /* #.#..... */
+ /*0304:*/ 0xc0, /* ##...... */
+ /*0305:*/ 0x80, /* #....... */
+ /*0306:*/ 0x80, /* #....... */
+/* --- new character q (113) starting at offset 0x0307 --- */
+ /*0307:*/ 4, 4, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*030c:*/ 0x60, /* .##..... */
+ /*030d:*/ 0xa0, /* #.#..... */
+ /*030e:*/ 0xa0, /* #.#..... */
+ /*030f:*/ 0x60, /* .##..... */
+ /*0310:*/ 0x20, /* ..#..... */
+/* --- new character r (114) starting at offset 0x0311 --- */
+ /*0311:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0316:*/ 0xa0, /* #.#..... */
+ /*0317:*/ 0xc0, /* ##...... */
+ /*0318:*/ 0x80, /* #....... */
+ /*0319:*/ 0x80, /* #....... */
+/* --- new character s (115) starting at offset 0x031a --- */
+ /*031a:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*031f:*/ 0x60, /* .##..... */
+ /*0320:*/ 0xc0, /* ##...... */
+ /*0321:*/ 0x20, /* ..#..... */
+ /*0322:*/ 0xc0, /* ##...... */
+/* --- new character t (116) starting at offset 0x0323 --- */
+ /*0323:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0328:*/ 0x40, /* .#...... */
+ /*0329:*/ 0xe0, /* ###..... */
+ /*032a:*/ 0x40, /* .#...... */
+ /*032b:*/ 0x40, /* .#...... */
+ /*032c:*/ 0x20, /* ..#..... */
+/* --- new character u (117) starting at offset 0x032d --- */
+ /*032d:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0332:*/ 0xa0, /* #.#..... */
+ /*0333:*/ 0xa0, /* #.#..... */
+ /*0334:*/ 0xa0, /* #.#..... */
+ /*0335:*/ 0x60, /* .##..... */
+/* --- new character v (118) starting at offset 0x0336 --- */
+ /*0336:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*033b:*/ 0xa0, /* #.#..... */
+ /*033c:*/ 0xa0, /* #.#..... */
+ /*033d:*/ 0xa0, /* #.#..... */
+ /*033e:*/ 0x40, /* .#...... */
+/* --- new character w (119) starting at offset 0x033f --- */
+ /*033f:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0344:*/ 0xa0, /* #.#..... */
+ /*0345:*/ 0xa0, /* #.#..... */
+ /*0346:*/ 0xe0, /* ###..... */
+ /*0347:*/ 0xa0, /* #.#..... */
+/* --- new character x (120) starting at offset 0x0348 --- */
+ /*0348:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*034d:*/ 0xa0, /* #.#..... */
+ /*034e:*/ 0x40, /* .#...... */
+ /*034f:*/ 0x40, /* .#...... */
+ /*0350:*/ 0xa0, /* #.#..... */
+/* --- new character y (121) starting at offset 0x0351 --- */
+ /*0351:*/ 4, 4, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0356:*/ 0xa0, /* #.#..... */
+ /*0357:*/ 0xa0, /* #.#..... */
+ /*0358:*/ 0x60, /* .##..... */
+ /*0359:*/ 0x20, /* ..#..... */
+ /*035a:*/ 0xc0, /* ##...... */
+/* --- new character z (122) starting at offset 0x035b --- */
+ /*035b:*/ 4, 4, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0360:*/ 0xe0, /* ###..... */
+ /*0361:*/ 0x20, /* ..#..... */
+ /*0362:*/ 0x40, /* .#...... */
+ /*0363:*/ 0xe0, /* ###..... */
+/* --- new character braceleft (123) starting at offset 0x0364 --- */
+ /*0364:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0369:*/ 0x20, /* ..#..... */
+ /*036a:*/ 0x40, /* .#...... */
+ /*036b:*/ 0xc0, /* ##...... */
+ /*036c:*/ 0x40, /* .#...... */
+ /*036d:*/ 0x40, /* .#...... */
+ /*036e:*/ 0x20, /* ..#..... */
+/* --- new character bar (124) starting at offset 0x036f --- */
+ /*036f:*/ 4, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0374:*/ 0x40, /* .#...... */
+ /*0375:*/ 0x40, /* .#...... */
+ /*0376:*/ 0x40, /* .#...... */
+ /*0377:*/ 0x40, /* .#...... */
+ /*0378:*/ 0x40, /* .#...... */
+/* --- new character braceright (125) starting at offset 0x0379 --- */
+ /*0379:*/ 4, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*037e:*/ 0x80, /* #....... */
+ /*037f:*/ 0x40, /* .#...... */
+ /*0380:*/ 0x60, /* .##..... */
+ /*0381:*/ 0x40, /* .#...... */
+ /*0382:*/ 0x40, /* .#...... */
+ /*0383:*/ 0x80, /* #....... */
+/* --- new character asciitilde (126) starting at offset 0x0384 --- */
+ /*0384:*/ 4, 4, 2, 0, 3, /* width and bbox (w,h,x,y) */
+ /*0389:*/ 0x50, /* .#.#.... */
+ /*038a:*/ 0xa0, /* #.#..... */
+};
+static const uint16_t font_4x6_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x0010 /* quotedbl */,
+ 0x0017 /* numbersign */,
+ 0x0021 /* dollar */,
+ 0x002c /* percent */,
+ 0x0036 /* ampersand */,
+ 0x0040 /* quotesingle */,
+ 0x0047 /* parenleft */,
+ 0x0052 /* parenright */,
+ 0x005d /* asterisk */,
+ 0x0067 /* plus */,
+ 0x0071 /* comma */,
+ 0x0078 /* hyphen */,
+ 0x007e /* period */,
+ 0x0084 /* slash */,
+ 0x008e /* zero */,
+ 0x0098 /* one */,
+ 0x00a2 /* two */,
+ 0x00ac /* three */,
+ 0x00b6 /* four */,
+ 0x00c0 /* five */,
+ 0x00ca /* six */,
+ 0x00d4 /* seven */,
+ 0x00de /* eight */,
+ 0x00e8 /* nine */,
+ 0x00f2 /* colon */,
+ 0x00fb /* semicolon */,
+ 0x0105 /* less */,
+ 0x010f /* equal */,
+ 0x0117 /* greater */,
+ 0x0121 /* question */,
+ 0x012b /* at */,
+ 0x0135 /* A */,
+ 0x013f /* B */,
+ 0x0149 /* C */,
+ 0x0153 /* D */,
+ 0x015d /* E */,
+ 0x0167 /* F */,
+ 0x0171 /* G */,
+ 0x017b /* H */,
+ 0x0185 /* I */,
+ 0x018f /* J */,
+ 0x0199 /* K */,
+ 0x01a3 /* L */,
+ 0x01ad /* M */,
+ 0x01b7 /* N */,
+ 0x01c1 /* O */,
+ 0x01cb /* P */,
+ 0x01d5 /* Q */,
+ 0x01e0 /* R */,
+ 0x01ea /* S */,
+ 0x01f4 /* T */,
+ 0x01fe /* U */,
+ 0x0208 /* V */,
+ 0x0212 /* W */,
+ 0x021c /* X */,
+ 0x0226 /* Y */,
+ 0x0230 /* Z */,
+ 0x023a /* bracketleft */,
+ 0x0244 /* backslash */,
+ 0x024e /* bracketright */,
+ 0x0258 /* asciicircum */,
+ 0x025f /* underscore */,
+ 0x0265 /* grave */,
+ 0x026c /* a */,
+ 0x0275 /* b */,
+ 0x027f /* c */,
+ 0x0288 /* d */,
+ 0x0292 /* e */,
+ 0x029b /* f */,
+ 0x02a5 /* g */,
+ 0x02af /* h */,
+ 0x02b9 /* i */,
+ 0x02c3 /* j */,
+ 0x02ce /* k */,
+ 0x02d8 /* l */,
+ 0x02e2 /* m */,
+ 0x02eb /* n */,
+ 0x02f4 /* o */,
+ 0x02fd /* p */,
+ 0x0307 /* q */,
+ 0x0311 /* r */,
+ 0x031a /* s */,
+ 0x0323 /* t */,
+ 0x032d /* u */,
+ 0x0336 /* v */,
+ 0x033f /* w */,
+ 0x0348 /* x */,
+ 0x0351 /* y */,
+ 0x035b /* z */,
+ 0x0364 /* braceleft */,
+ 0x036f /* bar */,
+ 0x0379 /* braceright */,
+ 0x0384 /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_4x6 = {
+ .height = 6,
+ .ascent = 5,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_4x6_data,
+ .charoffs = font_4x6_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/5x8.c b/Src/osmolib/src/target/firmware/fb/5x8.c
new file mode 100644
index 0000000..e200329
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/5x8.c
@@ -0,0 +1,802 @@
+#include <fb/font.h>
+static const uint8_t font_5x8_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 5, 5, 1, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0x20, /* ..#..... */
+ /*000c:*/ 0x20, /* ..#..... */
+ /*000d:*/ 0x20, /* ..#..... */
+ /*000e:*/ 0x20, /* ..#..... */
+ /*000f:*/ 0x00, /* ........ */
+ /*0010:*/ 0x20, /* ..#..... */
+/* --- new character quotedbl (34) starting at offset 0x0011 --- */
+ /*0011:*/ 5, 5, 3, 0, 3, /* width and bbox (w,h,x,y) */
+ /*0016:*/ 0x50, /* .#.#.... */
+ /*0017:*/ 0x50, /* .#.#.... */
+ /*0018:*/ 0x50, /* .#.#.... */
+/* --- new character numbersign (35) starting at offset 0x0019 --- */
+ /*0019:*/ 5, 5, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*001e:*/ 0x50, /* .#.#.... */
+ /*001f:*/ 0x50, /* .#.#.... */
+ /*0020:*/ 0xf8, /* #####... */
+ /*0021:*/ 0x50, /* .#.#.... */
+ /*0022:*/ 0xf8, /* #####... */
+ /*0023:*/ 0x50, /* .#.#.... */
+ /*0024:*/ 0x50, /* .#.#.... */
+/* --- new character dollar (36) starting at offset 0x0025 --- */
+ /*0025:*/ 5, 5, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*002a:*/ 0x20, /* ..#..... */
+ /*002b:*/ 0x70, /* .###.... */
+ /*002c:*/ 0xa0, /* #.#..... */
+ /*002d:*/ 0x70, /* .###.... */
+ /*002e:*/ 0x28, /* ..#.#... */
+ /*002f:*/ 0x70, /* .###.... */
+ /*0030:*/ 0x20, /* ..#..... */
+/* --- new character percent (37) starting at offset 0x0031 --- */
+ /*0031:*/ 5, 5, 5, 0, 1, /* width and bbox (w,h,x,y) */
+ /*0036:*/ 0x40, /* .#...... */
+ /*0037:*/ 0x50, /* .#.#.... */
+ /*0038:*/ 0x20, /* ..#..... */
+ /*0039:*/ 0x50, /* .#.#.... */
+ /*003a:*/ 0x10, /* ...#.... */
+/* --- new character ampersand (38) starting at offset 0x003b --- */
+ /*003b:*/ 5, 5, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0040:*/ 0x40, /* .#...... */
+ /*0041:*/ 0xa0, /* #.#..... */
+ /*0042:*/ 0xa0, /* #.#..... */
+ /*0043:*/ 0x40, /* .#...... */
+ /*0044:*/ 0xa0, /* #.#..... */
+ /*0045:*/ 0xa0, /* #.#..... */
+ /*0046:*/ 0x50, /* .#.#.... */
+/* --- new character quotesingle (39) starting at offset 0x0047 --- */
+ /*0047:*/ 5, 5, 3, 0, 3, /* width and bbox (w,h,x,y) */
+ /*004c:*/ 0x20, /* ..#..... */
+ /*004d:*/ 0x20, /* ..#..... */
+ /*004e:*/ 0x20, /* ..#..... */
+/* --- new character parenleft (40) starting at offset 0x004f --- */
+ /*004f:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0054:*/ 0x20, /* ..#..... */
+ /*0055:*/ 0x40, /* .#...... */
+ /*0056:*/ 0x40, /* .#...... */
+ /*0057:*/ 0x40, /* .#...... */
+ /*0058:*/ 0x40, /* .#...... */
+ /*0059:*/ 0x20, /* ..#..... */
+/* --- new character parenright (41) starting at offset 0x005a --- */
+ /*005a:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*005f:*/ 0x40, /* .#...... */
+ /*0060:*/ 0x20, /* ..#..... */
+ /*0061:*/ 0x20, /* ..#..... */
+ /*0062:*/ 0x20, /* ..#..... */
+ /*0063:*/ 0x20, /* ..#..... */
+ /*0064:*/ 0x40, /* .#...... */
+/* --- new character asterisk (42) starting at offset 0x0065 --- */
+ /*0065:*/ 5, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*006a:*/ 0x90, /* #..#.... */
+ /*006b:*/ 0x60, /* .##..... */
+ /*006c:*/ 0xf0, /* ####.... */
+ /*006d:*/ 0x60, /* .##..... */
+ /*006e:*/ 0x90, /* #..#.... */
+/* --- new character plus (43) starting at offset 0x006f --- */
+ /*006f:*/ 5, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0074:*/ 0x20, /* ..#..... */
+ /*0075:*/ 0x20, /* ..#..... */
+ /*0076:*/ 0xf8, /* #####... */
+ /*0077:*/ 0x20, /* ..#..... */
+ /*0078:*/ 0x20, /* ..#..... */
+/* --- new character comma (44) starting at offset 0x0079 --- */
+ /*0079:*/ 5, 5, 3, 0, -1, /* width and bbox (w,h,x,y) */
+ /*007e:*/ 0x30, /* ..##.... */
+ /*007f:*/ 0x20, /* ..#..... */
+ /*0080:*/ 0x40, /* .#...... */
+/* --- new character hyphen (45) starting at offset 0x0081 --- */
+ /*0081:*/ 5, 5, 1, 0, 2, /* width and bbox (w,h,x,y) */
+ /*0086:*/ 0x70, /* .###.... */
+/* --- new character period (46) starting at offset 0x0087 --- */
+ /*0087:*/ 5, 5, 3, 0, -1, /* width and bbox (w,h,x,y) */
+ /*008c:*/ 0x20, /* ..#..... */
+ /*008d:*/ 0x70, /* .###.... */
+ /*008e:*/ 0x20, /* ..#..... */
+/* --- new character slash (47) starting at offset 0x008f --- */
+ /*008f:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0094:*/ 0x10, /* ...#.... */
+ /*0095:*/ 0x10, /* ...#.... */
+ /*0096:*/ 0x20, /* ..#..... */
+ /*0097:*/ 0x40, /* .#...... */
+ /*0098:*/ 0x80, /* #....... */
+ /*0099:*/ 0x80, /* #....... */
+/* --- new character zero (48) starting at offset 0x009a --- */
+ /*009a:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*009f:*/ 0x20, /* ..#..... */
+ /*00a0:*/ 0x50, /* .#.#.... */
+ /*00a1:*/ 0x50, /* .#.#.... */
+ /*00a2:*/ 0x50, /* .#.#.... */
+ /*00a3:*/ 0x50, /* .#.#.... */
+ /*00a4:*/ 0x20, /* ..#..... */
+/* --- new character one (49) starting at offset 0x00a5 --- */
+ /*00a5:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00aa:*/ 0x20, /* ..#..... */
+ /*00ab:*/ 0x60, /* .##..... */
+ /*00ac:*/ 0x20, /* ..#..... */
+ /*00ad:*/ 0x20, /* ..#..... */
+ /*00ae:*/ 0x20, /* ..#..... */
+ /*00af:*/ 0x70, /* .###.... */
+/* --- new character two (50) starting at offset 0x00b0 --- */
+ /*00b0:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00b5:*/ 0x60, /* .##..... */
+ /*00b6:*/ 0x90, /* #..#.... */
+ /*00b7:*/ 0x10, /* ...#.... */
+ /*00b8:*/ 0x60, /* .##..... */
+ /*00b9:*/ 0x80, /* #....... */
+ /*00ba:*/ 0xf0, /* ####.... */
+/* --- new character three (51) starting at offset 0x00bb --- */
+ /*00bb:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00c0:*/ 0xf0, /* ####.... */
+ /*00c1:*/ 0x20, /* ..#..... */
+ /*00c2:*/ 0x60, /* .##..... */
+ /*00c3:*/ 0x10, /* ...#.... */
+ /*00c4:*/ 0x90, /* #..#.... */
+ /*00c5:*/ 0x60, /* .##..... */
+/* --- new character four (52) starting at offset 0x00c6 --- */
+ /*00c6:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00cb:*/ 0x20, /* ..#..... */
+ /*00cc:*/ 0x60, /* .##..... */
+ /*00cd:*/ 0xa0, /* #.#..... */
+ /*00ce:*/ 0xf0, /* ####.... */
+ /*00cf:*/ 0x20, /* ..#..... */
+ /*00d0:*/ 0x20, /* ..#..... */
+/* --- new character five (53) starting at offset 0x00d1 --- */
+ /*00d1:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00d6:*/ 0xf0, /* ####.... */
+ /*00d7:*/ 0x80, /* #....... */
+ /*00d8:*/ 0xe0, /* ###..... */
+ /*00d9:*/ 0x10, /* ...#.... */
+ /*00da:*/ 0x90, /* #..#.... */
+ /*00db:*/ 0x60, /* .##..... */
+/* --- new character six (54) starting at offset 0x00dc --- */
+ /*00dc:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00e1:*/ 0x60, /* .##..... */
+ /*00e2:*/ 0x80, /* #....... */
+ /*00e3:*/ 0xe0, /* ###..... */
+ /*00e4:*/ 0x90, /* #..#.... */
+ /*00e5:*/ 0x90, /* #..#.... */
+ /*00e6:*/ 0x60, /* .##..... */
+/* --- new character seven (55) starting at offset 0x00e7 --- */
+ /*00e7:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00ec:*/ 0xf0, /* ####.... */
+ /*00ed:*/ 0x10, /* ...#.... */
+ /*00ee:*/ 0x20, /* ..#..... */
+ /*00ef:*/ 0x20, /* ..#..... */
+ /*00f0:*/ 0x40, /* .#...... */
+ /*00f1:*/ 0x40, /* .#...... */
+/* --- new character eight (56) starting at offset 0x00f2 --- */
+ /*00f2:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00f7:*/ 0x60, /* .##..... */
+ /*00f8:*/ 0x90, /* #..#.... */
+ /*00f9:*/ 0x60, /* .##..... */
+ /*00fa:*/ 0x90, /* #..#.... */
+ /*00fb:*/ 0x90, /* #..#.... */
+ /*00fc:*/ 0x60, /* .##..... */
+/* --- new character nine (57) starting at offset 0x00fd --- */
+ /*00fd:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0102:*/ 0x60, /* .##..... */
+ /*0103:*/ 0x90, /* #..#.... */
+ /*0104:*/ 0x90, /* #..#.... */
+ /*0105:*/ 0x70, /* .###.... */
+ /*0106:*/ 0x10, /* ...#.... */
+ /*0107:*/ 0x60, /* .##..... */
+/* --- new character colon (58) starting at offset 0x0108 --- */
+ /*0108:*/ 5, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*010d:*/ 0x60, /* .##..... */
+ /*010e:*/ 0x60, /* .##..... */
+ /*010f:*/ 0x00, /* ........ */
+ /*0110:*/ 0x60, /* .##..... */
+ /*0111:*/ 0x60, /* .##..... */
+/* --- new character semicolon (59) starting at offset 0x0112 --- */
+ /*0112:*/ 5, 5, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0117:*/ 0x30, /* ..##.... */
+ /*0118:*/ 0x30, /* ..##.... */
+ /*0119:*/ 0x00, /* ........ */
+ /*011a:*/ 0x30, /* ..##.... */
+ /*011b:*/ 0x20, /* ..#..... */
+ /*011c:*/ 0x40, /* .#...... */
+/* --- new character less (60) starting at offset 0x011d --- */
+ /*011d:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0122:*/ 0x10, /* ...#.... */
+ /*0123:*/ 0x20, /* ..#..... */
+ /*0124:*/ 0x40, /* .#...... */
+ /*0125:*/ 0x40, /* .#...... */
+ /*0126:*/ 0x20, /* ..#..... */
+ /*0127:*/ 0x10, /* ...#.... */
+/* --- new character equal (61) starting at offset 0x0128 --- */
+ /*0128:*/ 5, 5, 3, 0, 1, /* width and bbox (w,h,x,y) */
+ /*012d:*/ 0xf0, /* ####.... */
+ /*012e:*/ 0x00, /* ........ */
+ /*012f:*/ 0xf0, /* ####.... */
+/* --- new character greater (62) starting at offset 0x0130 --- */
+ /*0130:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0135:*/ 0x40, /* .#...... */
+ /*0136:*/ 0x20, /* ..#..... */
+ /*0137:*/ 0x10, /* ...#.... */
+ /*0138:*/ 0x10, /* ...#.... */
+ /*0139:*/ 0x20, /* ..#..... */
+ /*013a:*/ 0x40, /* .#...... */
+/* --- new character question (63) starting at offset 0x013b --- */
+ /*013b:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0140:*/ 0x20, /* ..#..... */
+ /*0141:*/ 0x50, /* .#.#.... */
+ /*0142:*/ 0x10, /* ...#.... */
+ /*0143:*/ 0x20, /* ..#..... */
+ /*0144:*/ 0x00, /* ........ */
+ /*0145:*/ 0x20, /* ..#..... */
+/* --- new character at (64) starting at offset 0x0146 --- */
+ /*0146:*/ 5, 5, 8, 0, -1, /* width and bbox (w,h,x,y) */
+ /*014b:*/ 0x30, /* ..##.... */
+ /*014c:*/ 0x48, /* .#..#... */
+ /*014d:*/ 0x98, /* #..##... */
+ /*014e:*/ 0xa8, /* #.#.#... */
+ /*014f:*/ 0xa8, /* #.#.#... */
+ /*0150:*/ 0x90, /* #..#.... */
+ /*0151:*/ 0x40, /* .#...... */
+ /*0152:*/ 0x30, /* ..##.... */
+/* --- new character A (65) starting at offset 0x0153 --- */
+ /*0153:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0158:*/ 0x60, /* .##..... */
+ /*0159:*/ 0x90, /* #..#.... */
+ /*015a:*/ 0x90, /* #..#.... */
+ /*015b:*/ 0xf0, /* ####.... */
+ /*015c:*/ 0x90, /* #..#.... */
+ /*015d:*/ 0x90, /* #..#.... */
+/* --- new character B (66) starting at offset 0x015e --- */
+ /*015e:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0163:*/ 0xe0, /* ###..... */
+ /*0164:*/ 0x90, /* #..#.... */
+ /*0165:*/ 0xe0, /* ###..... */
+ /*0166:*/ 0x90, /* #..#.... */
+ /*0167:*/ 0x90, /* #..#.... */
+ /*0168:*/ 0xe0, /* ###..... */
+/* --- new character C (67) starting at offset 0x0169 --- */
+ /*0169:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*016e:*/ 0x60, /* .##..... */
+ /*016f:*/ 0x90, /* #..#.... */
+ /*0170:*/ 0x80, /* #....... */
+ /*0171:*/ 0x80, /* #....... */
+ /*0172:*/ 0x90, /* #..#.... */
+ /*0173:*/ 0x60, /* .##..... */
+/* --- new character D (68) starting at offset 0x0174 --- */
+ /*0174:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0179:*/ 0xe0, /* ###..... */
+ /*017a:*/ 0x90, /* #..#.... */
+ /*017b:*/ 0x90, /* #..#.... */
+ /*017c:*/ 0x90, /* #..#.... */
+ /*017d:*/ 0x90, /* #..#.... */
+ /*017e:*/ 0xe0, /* ###..... */
+/* --- new character E (69) starting at offset 0x017f --- */
+ /*017f:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0184:*/ 0xf0, /* ####.... */
+ /*0185:*/ 0x80, /* #....... */
+ /*0186:*/ 0xe0, /* ###..... */
+ /*0187:*/ 0x80, /* #....... */
+ /*0188:*/ 0x80, /* #....... */
+ /*0189:*/ 0xf0, /* ####.... */
+/* --- new character F (70) starting at offset 0x018a --- */
+ /*018a:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*018f:*/ 0xf0, /* ####.... */
+ /*0190:*/ 0x80, /* #....... */
+ /*0191:*/ 0xe0, /* ###..... */
+ /*0192:*/ 0x80, /* #....... */
+ /*0193:*/ 0x80, /* #....... */
+ /*0194:*/ 0x80, /* #....... */
+/* --- new character G (71) starting at offset 0x0195 --- */
+ /*0195:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*019a:*/ 0x60, /* .##..... */
+ /*019b:*/ 0x90, /* #..#.... */
+ /*019c:*/ 0x80, /* #....... */
+ /*019d:*/ 0xb0, /* #.##.... */
+ /*019e:*/ 0x90, /* #..#.... */
+ /*019f:*/ 0x60, /* .##..... */
+/* --- new character H (72) starting at offset 0x01a0 --- */
+ /*01a0:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01a5:*/ 0x90, /* #..#.... */
+ /*01a6:*/ 0x90, /* #..#.... */
+ /*01a7:*/ 0xf0, /* ####.... */
+ /*01a8:*/ 0x90, /* #..#.... */
+ /*01a9:*/ 0x90, /* #..#.... */
+ /*01aa:*/ 0x90, /* #..#.... */
+/* --- new character I (73) starting at offset 0x01ab --- */
+ /*01ab:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01b0:*/ 0x70, /* .###.... */
+ /*01b1:*/ 0x20, /* ..#..... */
+ /*01b2:*/ 0x20, /* ..#..... */
+ /*01b3:*/ 0x20, /* ..#..... */
+ /*01b4:*/ 0x20, /* ..#..... */
+ /*01b5:*/ 0x70, /* .###.... */
+/* --- new character J (74) starting at offset 0x01b6 --- */
+ /*01b6:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01bb:*/ 0x70, /* .###.... */
+ /*01bc:*/ 0x20, /* ..#..... */
+ /*01bd:*/ 0x20, /* ..#..... */
+ /*01be:*/ 0x20, /* ..#..... */
+ /*01bf:*/ 0xa0, /* #.#..... */
+ /*01c0:*/ 0x40, /* .#...... */
+/* --- new character K (75) starting at offset 0x01c1 --- */
+ /*01c1:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01c6:*/ 0x90, /* #..#.... */
+ /*01c7:*/ 0xa0, /* #.#..... */
+ /*01c8:*/ 0xc0, /* ##...... */
+ /*01c9:*/ 0xa0, /* #.#..... */
+ /*01ca:*/ 0xa0, /* #.#..... */
+ /*01cb:*/ 0x90, /* #..#.... */
+/* --- new character L (76) starting at offset 0x01cc --- */
+ /*01cc:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01d1:*/ 0x80, /* #....... */
+ /*01d2:*/ 0x80, /* #....... */
+ /*01d3:*/ 0x80, /* #....... */
+ /*01d4:*/ 0x80, /* #....... */
+ /*01d5:*/ 0x80, /* #....... */
+ /*01d6:*/ 0xf0, /* ####.... */
+/* --- new character M (77) starting at offset 0x01d7 --- */
+ /*01d7:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01dc:*/ 0x90, /* #..#.... */
+ /*01dd:*/ 0xf0, /* ####.... */
+ /*01de:*/ 0xf0, /* ####.... */
+ /*01df:*/ 0x90, /* #..#.... */
+ /*01e0:*/ 0x90, /* #..#.... */
+ /*01e1:*/ 0x90, /* #..#.... */
+/* --- new character N (78) starting at offset 0x01e2 --- */
+ /*01e2:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01e7:*/ 0x90, /* #..#.... */
+ /*01e8:*/ 0xd0, /* ##.#.... */
+ /*01e9:*/ 0xf0, /* ####.... */
+ /*01ea:*/ 0xb0, /* #.##.... */
+ /*01eb:*/ 0xb0, /* #.##.... */
+ /*01ec:*/ 0x90, /* #..#.... */
+/* --- new character O (79) starting at offset 0x01ed --- */
+ /*01ed:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01f2:*/ 0x60, /* .##..... */
+ /*01f3:*/ 0x90, /* #..#.... */
+ /*01f4:*/ 0x90, /* #..#.... */
+ /*01f5:*/ 0x90, /* #..#.... */
+ /*01f6:*/ 0x90, /* #..#.... */
+ /*01f7:*/ 0x60, /* .##..... */
+/* --- new character P (80) starting at offset 0x01f8 --- */
+ /*01f8:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01fd:*/ 0xe0, /* ###..... */
+ /*01fe:*/ 0x90, /* #..#.... */
+ /*01ff:*/ 0x90, /* #..#.... */
+ /*0200:*/ 0xe0, /* ###..... */
+ /*0201:*/ 0x80, /* #....... */
+ /*0202:*/ 0x80, /* #....... */
+/* --- new character Q (81) starting at offset 0x0203 --- */
+ /*0203:*/ 5, 5, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0208:*/ 0x60, /* .##..... */
+ /*0209:*/ 0x90, /* #..#.... */
+ /*020a:*/ 0x90, /* #..#.... */
+ /*020b:*/ 0xd0, /* ##.#.... */
+ /*020c:*/ 0xb0, /* #.##.... */
+ /*020d:*/ 0x60, /* .##..... */
+ /*020e:*/ 0x10, /* ...#.... */
+/* --- new character R (82) starting at offset 0x020f --- */
+ /*020f:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0214:*/ 0xe0, /* ###..... */
+ /*0215:*/ 0x90, /* #..#.... */
+ /*0216:*/ 0x90, /* #..#.... */
+ /*0217:*/ 0xe0, /* ###..... */
+ /*0218:*/ 0x90, /* #..#.... */
+ /*0219:*/ 0x90, /* #..#.... */
+/* --- new character S (83) starting at offset 0x021a --- */
+ /*021a:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*021f:*/ 0x60, /* .##..... */
+ /*0220:*/ 0x90, /* #..#.... */
+ /*0221:*/ 0x40, /* .#...... */
+ /*0222:*/ 0x20, /* ..#..... */
+ /*0223:*/ 0x90, /* #..#.... */
+ /*0224:*/ 0x60, /* .##..... */
+/* --- new character T (84) starting at offset 0x0225 --- */
+ /*0225:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*022a:*/ 0x70, /* .###.... */
+ /*022b:*/ 0x20, /* ..#..... */
+ /*022c:*/ 0x20, /* ..#..... */
+ /*022d:*/ 0x20, /* ..#..... */
+ /*022e:*/ 0x20, /* ..#..... */
+ /*022f:*/ 0x20, /* ..#..... */
+/* --- new character U (85) starting at offset 0x0230 --- */
+ /*0230:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0235:*/ 0x90, /* #..#.... */
+ /*0236:*/ 0x90, /* #..#.... */
+ /*0237:*/ 0x90, /* #..#.... */
+ /*0238:*/ 0x90, /* #..#.... */
+ /*0239:*/ 0x90, /* #..#.... */
+ /*023a:*/ 0x60, /* .##..... */
+/* --- new character V (86) starting at offset 0x023b --- */
+ /*023b:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0240:*/ 0x90, /* #..#.... */
+ /*0241:*/ 0x90, /* #..#.... */
+ /*0242:*/ 0x90, /* #..#.... */
+ /*0243:*/ 0x90, /* #..#.... */
+ /*0244:*/ 0x60, /* .##..... */
+ /*0245:*/ 0x60, /* .##..... */
+/* --- new character W (87) starting at offset 0x0246 --- */
+ /*0246:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*024b:*/ 0x90, /* #..#.... */
+ /*024c:*/ 0x90, /* #..#.... */
+ /*024d:*/ 0x90, /* #..#.... */
+ /*024e:*/ 0xf0, /* ####.... */
+ /*024f:*/ 0xf0, /* ####.... */
+ /*0250:*/ 0x90, /* #..#.... */
+/* --- new character X (88) starting at offset 0x0251 --- */
+ /*0251:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0256:*/ 0x90, /* #..#.... */
+ /*0257:*/ 0x90, /* #..#.... */
+ /*0258:*/ 0x60, /* .##..... */
+ /*0259:*/ 0x60, /* .##..... */
+ /*025a:*/ 0x90, /* #..#.... */
+ /*025b:*/ 0x90, /* #..#.... */
+/* --- new character Y (89) starting at offset 0x025c --- */
+ /*025c:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0261:*/ 0x88, /* #...#... */
+ /*0262:*/ 0x88, /* #...#... */
+ /*0263:*/ 0x50, /* .#.#.... */
+ /*0264:*/ 0x20, /* ..#..... */
+ /*0265:*/ 0x20, /* ..#..... */
+ /*0266:*/ 0x20, /* ..#..... */
+/* --- new character Z (90) starting at offset 0x0267 --- */
+ /*0267:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*026c:*/ 0xf0, /* ####.... */
+ /*026d:*/ 0x10, /* ...#.... */
+ /*026e:*/ 0x20, /* ..#..... */
+ /*026f:*/ 0x40, /* .#...... */
+ /*0270:*/ 0x80, /* #....... */
+ /*0271:*/ 0xf0, /* ####.... */
+/* --- new character bracketleft (91) starting at offset 0x0272 --- */
+ /*0272:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0277:*/ 0x70, /* .###.... */
+ /*0278:*/ 0x40, /* .#...... */
+ /*0279:*/ 0x40, /* .#...... */
+ /*027a:*/ 0x40, /* .#...... */
+ /*027b:*/ 0x40, /* .#...... */
+ /*027c:*/ 0x70, /* .###.... */
+/* --- new character backslash (92) starting at offset 0x027d --- */
+ /*027d:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0282:*/ 0x80, /* #....... */
+ /*0283:*/ 0x80, /* #....... */
+ /*0284:*/ 0x40, /* .#...... */
+ /*0285:*/ 0x20, /* ..#..... */
+ /*0286:*/ 0x10, /* ...#.... */
+ /*0287:*/ 0x10, /* ...#.... */
+/* --- new character bracketright (93) starting at offset 0x0288 --- */
+ /*0288:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*028d:*/ 0x70, /* .###.... */
+ /*028e:*/ 0x10, /* ...#.... */
+ /*028f:*/ 0x10, /* ...#.... */
+ /*0290:*/ 0x10, /* ...#.... */
+ /*0291:*/ 0x10, /* ...#.... */
+ /*0292:*/ 0x70, /* .###.... */
+/* --- new character asciicircum (94) starting at offset 0x0293 --- */
+ /*0293:*/ 5, 5, 2, 0, 4, /* width and bbox (w,h,x,y) */
+ /*0298:*/ 0x20, /* ..#..... */
+ /*0299:*/ 0x50, /* .#.#.... */
+/* --- new character underscore (95) starting at offset 0x029a --- */
+ /*029a:*/ 5, 5, 1, 0, -1, /* width and bbox (w,h,x,y) */
+ /*029f:*/ 0xf0, /* ####.... */
+/* --- new character grave (96) starting at offset 0x02a0 --- */
+ /*02a0:*/ 5, 5, 2, 0, 4, /* width and bbox (w,h,x,y) */
+ /*02a5:*/ 0x40, /* .#...... */
+ /*02a6:*/ 0x20, /* ..#..... */
+/* --- new character a (97) starting at offset 0x02a7 --- */
+ /*02a7:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02ac:*/ 0x70, /* .###.... */
+ /*02ad:*/ 0x90, /* #..#.... */
+ /*02ae:*/ 0x90, /* #..#.... */
+ /*02af:*/ 0x70, /* .###.... */
+/* --- new character b (98) starting at offset 0x02b0 --- */
+ /*02b0:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02b5:*/ 0x80, /* #....... */
+ /*02b6:*/ 0x80, /* #....... */
+ /*02b7:*/ 0xe0, /* ###..... */
+ /*02b8:*/ 0x90, /* #..#.... */
+ /*02b9:*/ 0x90, /* #..#.... */
+ /*02ba:*/ 0xe0, /* ###..... */
+/* --- new character c (99) starting at offset 0x02bb --- */
+ /*02bb:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02c0:*/ 0x30, /* ..##.... */
+ /*02c1:*/ 0x40, /* .#...... */
+ /*02c2:*/ 0x40, /* .#...... */
+ /*02c3:*/ 0x30, /* ..##.... */
+/* --- new character d (100) starting at offset 0x02c4 --- */
+ /*02c4:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02c9:*/ 0x10, /* ...#.... */
+ /*02ca:*/ 0x10, /* ...#.... */
+ /*02cb:*/ 0x70, /* .###.... */
+ /*02cc:*/ 0x90, /* #..#.... */
+ /*02cd:*/ 0x90, /* #..#.... */
+ /*02ce:*/ 0x70, /* .###.... */
+/* --- new character e (101) starting at offset 0x02cf --- */
+ /*02cf:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02d4:*/ 0x60, /* .##..... */
+ /*02d5:*/ 0xb0, /* #.##.... */
+ /*02d6:*/ 0xc0, /* ##...... */
+ /*02d7:*/ 0x60, /* .##..... */
+/* --- new character f (102) starting at offset 0x02d8 --- */
+ /*02d8:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02dd:*/ 0x20, /* ..#..... */
+ /*02de:*/ 0x50, /* .#.#.... */
+ /*02df:*/ 0x40, /* .#...... */
+ /*02e0:*/ 0xe0, /* ###..... */
+ /*02e1:*/ 0x40, /* .#...... */
+ /*02e2:*/ 0x40, /* .#...... */
+/* --- new character g (103) starting at offset 0x02e3 --- */
+ /*02e3:*/ 5, 5, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*02e8:*/ 0x60, /* .##..... */
+ /*02e9:*/ 0x90, /* #..#.... */
+ /*02ea:*/ 0x70, /* .###.... */
+ /*02eb:*/ 0x10, /* ...#.... */
+ /*02ec:*/ 0x60, /* .##..... */
+/* --- new character h (104) starting at offset 0x02ed --- */
+ /*02ed:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02f2:*/ 0x80, /* #....... */
+ /*02f3:*/ 0x80, /* #....... */
+ /*02f4:*/ 0xe0, /* ###..... */
+ /*02f5:*/ 0x90, /* #..#.... */
+ /*02f6:*/ 0x90, /* #..#.... */
+ /*02f7:*/ 0x90, /* #..#.... */
+/* --- new character i (105) starting at offset 0x02f8 --- */
+ /*02f8:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02fd:*/ 0x20, /* ..#..... */
+ /*02fe:*/ 0x00, /* ........ */
+ /*02ff:*/ 0x60, /* .##..... */
+ /*0300:*/ 0x20, /* ..#..... */
+ /*0301:*/ 0x20, /* ..#..... */
+ /*0302:*/ 0x70, /* .###.... */
+/* --- new character j (106) starting at offset 0x0303 --- */
+ /*0303:*/ 5, 5, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0308:*/ 0x10, /* ...#.... */
+ /*0309:*/ 0x00, /* ........ */
+ /*030a:*/ 0x10, /* ...#.... */
+ /*030b:*/ 0x10, /* ...#.... */
+ /*030c:*/ 0x10, /* ...#.... */
+ /*030d:*/ 0x50, /* .#.#.... */
+ /*030e:*/ 0x20, /* ..#..... */
+/* --- new character k (107) starting at offset 0x030f --- */
+ /*030f:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0314:*/ 0x80, /* #....... */
+ /*0315:*/ 0x80, /* #....... */
+ /*0316:*/ 0x90, /* #..#.... */
+ /*0317:*/ 0xe0, /* ###..... */
+ /*0318:*/ 0x90, /* #..#.... */
+ /*0319:*/ 0x90, /* #..#.... */
+/* --- new character l (108) starting at offset 0x031a --- */
+ /*031a:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*031f:*/ 0x60, /* .##..... */
+ /*0320:*/ 0x20, /* ..#..... */
+ /*0321:*/ 0x20, /* ..#..... */
+ /*0322:*/ 0x20, /* ..#..... */
+ /*0323:*/ 0x20, /* ..#..... */
+ /*0324:*/ 0x70, /* .###.... */
+/* --- new character m (109) starting at offset 0x0325 --- */
+ /*0325:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*032a:*/ 0xd0, /* ##.#.... */
+ /*032b:*/ 0xa8, /* #.#.#... */
+ /*032c:*/ 0xa8, /* #.#.#... */
+ /*032d:*/ 0xa8, /* #.#.#... */
+/* --- new character n (110) starting at offset 0x032e --- */
+ /*032e:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0333:*/ 0xe0, /* ###..... */
+ /*0334:*/ 0x90, /* #..#.... */
+ /*0335:*/ 0x90, /* #..#.... */
+ /*0336:*/ 0x90, /* #..#.... */
+/* --- new character o (111) starting at offset 0x0337 --- */
+ /*0337:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*033c:*/ 0x60, /* .##..... */
+ /*033d:*/ 0x90, /* #..#.... */
+ /*033e:*/ 0x90, /* #..#.... */
+ /*033f:*/ 0x60, /* .##..... */
+/* --- new character p (112) starting at offset 0x0340 --- */
+ /*0340:*/ 5, 5, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0345:*/ 0xe0, /* ###..... */
+ /*0346:*/ 0x90, /* #..#.... */
+ /*0347:*/ 0xe0, /* ###..... */
+ /*0348:*/ 0x80, /* #....... */
+ /*0349:*/ 0x80, /* #....... */
+/* --- new character q (113) starting at offset 0x034a --- */
+ /*034a:*/ 5, 5, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*034f:*/ 0x70, /* .###.... */
+ /*0350:*/ 0x90, /* #..#.... */
+ /*0351:*/ 0x70, /* .###.... */
+ /*0352:*/ 0x10, /* ...#.... */
+ /*0353:*/ 0x10, /* ...#.... */
+/* --- new character r (114) starting at offset 0x0354 --- */
+ /*0354:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0359:*/ 0xa0, /* #.#..... */
+ /*035a:*/ 0xd0, /* ##.#.... */
+ /*035b:*/ 0x80, /* #....... */
+ /*035c:*/ 0x80, /* #....... */
+/* --- new character s (115) starting at offset 0x035d --- */
+ /*035d:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0362:*/ 0x30, /* ..##.... */
+ /*0363:*/ 0x60, /* .##..... */
+ /*0364:*/ 0x10, /* ...#.... */
+ /*0365:*/ 0x60, /* .##..... */
+/* --- new character t (116) starting at offset 0x0366 --- */
+ /*0366:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*036b:*/ 0x40, /* .#...... */
+ /*036c:*/ 0x40, /* .#...... */
+ /*036d:*/ 0xe0, /* ###..... */
+ /*036e:*/ 0x40, /* .#...... */
+ /*036f:*/ 0x50, /* .#.#.... */
+ /*0370:*/ 0x20, /* ..#..... */
+/* --- new character u (117) starting at offset 0x0371 --- */
+ /*0371:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0376:*/ 0x90, /* #..#.... */
+ /*0377:*/ 0x90, /* #..#.... */
+ /*0378:*/ 0x90, /* #..#.... */
+ /*0379:*/ 0x70, /* .###.... */
+/* --- new character v (118) starting at offset 0x037a --- */
+ /*037a:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*037f:*/ 0x50, /* .#.#.... */
+ /*0380:*/ 0x50, /* .#.#.... */
+ /*0381:*/ 0x50, /* .#.#.... */
+ /*0382:*/ 0x20, /* ..#..... */
+/* --- new character w (119) starting at offset 0x0383 --- */
+ /*0383:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0388:*/ 0x88, /* #...#... */
+ /*0389:*/ 0xa8, /* #.#.#... */
+ /*038a:*/ 0xa8, /* #.#.#... */
+ /*038b:*/ 0x50, /* .#.#.... */
+/* --- new character x (120) starting at offset 0x038c --- */
+ /*038c:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0391:*/ 0x90, /* #..#.... */
+ /*0392:*/ 0x60, /* .##..... */
+ /*0393:*/ 0x60, /* .##..... */
+ /*0394:*/ 0x90, /* #..#.... */
+/* --- new character y (121) starting at offset 0x0395 --- */
+ /*0395:*/ 5, 5, 5, 0, -1, /* width and bbox (w,h,x,y) */
+ /*039a:*/ 0x90, /* #..#.... */
+ /*039b:*/ 0x90, /* #..#.... */
+ /*039c:*/ 0x70, /* .###.... */
+ /*039d:*/ 0x90, /* #..#.... */
+ /*039e:*/ 0x60, /* .##..... */
+/* --- new character z (122) starting at offset 0x039f --- */
+ /*039f:*/ 5, 5, 4, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03a4:*/ 0xf0, /* ####.... */
+ /*03a5:*/ 0x20, /* ..#..... */
+ /*03a6:*/ 0x40, /* .#...... */
+ /*03a7:*/ 0xf0, /* ####.... */
+/* --- new character braceleft (123) starting at offset 0x03a8 --- */
+ /*03a8:*/ 5, 5, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03ad:*/ 0x30, /* ..##.... */
+ /*03ae:*/ 0x40, /* .#...... */
+ /*03af:*/ 0x20, /* ..#..... */
+ /*03b0:*/ 0xc0, /* ##...... */
+ /*03b1:*/ 0x20, /* ..#..... */
+ /*03b2:*/ 0x40, /* .#...... */
+ /*03b3:*/ 0x30, /* ..##.... */
+/* --- new character bar (124) starting at offset 0x03b4 --- */
+ /*03b4:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03b9:*/ 0x20, /* ..#..... */
+ /*03ba:*/ 0x20, /* ..#..... */
+ /*03bb:*/ 0x20, /* ..#..... */
+ /*03bc:*/ 0x20, /* ..#..... */
+ /*03bd:*/ 0x20, /* ..#..... */
+ /*03be:*/ 0x20, /* ..#..... */
+/* --- new character braceright (125) starting at offset 0x03bf --- */
+ /*03bf:*/ 5, 5, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03c4:*/ 0xc0, /* ##...... */
+ /*03c5:*/ 0x20, /* ..#..... */
+ /*03c6:*/ 0x40, /* .#...... */
+ /*03c7:*/ 0x30, /* ..##.... */
+ /*03c8:*/ 0x40, /* .#...... */
+ /*03c9:*/ 0x20, /* ..#..... */
+ /*03ca:*/ 0xc0, /* ##...... */
+/* --- new character asciitilde (126) starting at offset 0x03cb --- */
+ /*03cb:*/ 5, 5, 2, 0, 4, /* width and bbox (w,h,x,y) */
+ /*03d0:*/ 0x50, /* .#.#.... */
+ /*03d1:*/ 0xa0, /* #.#..... */
+};
+static const uint16_t font_5x8_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x0011 /* quotedbl */,
+ 0x0019 /* numbersign */,
+ 0x0025 /* dollar */,
+ 0x0031 /* percent */,
+ 0x003b /* ampersand */,
+ 0x0047 /* quotesingle */,
+ 0x004f /* parenleft */,
+ 0x005a /* parenright */,
+ 0x0065 /* asterisk */,
+ 0x006f /* plus */,
+ 0x0079 /* comma */,
+ 0x0081 /* hyphen */,
+ 0x0087 /* period */,
+ 0x008f /* slash */,
+ 0x009a /* zero */,
+ 0x00a5 /* one */,
+ 0x00b0 /* two */,
+ 0x00bb /* three */,
+ 0x00c6 /* four */,
+ 0x00d1 /* five */,
+ 0x00dc /* six */,
+ 0x00e7 /* seven */,
+ 0x00f2 /* eight */,
+ 0x00fd /* nine */,
+ 0x0108 /* colon */,
+ 0x0112 /* semicolon */,
+ 0x011d /* less */,
+ 0x0128 /* equal */,
+ 0x0130 /* greater */,
+ 0x013b /* question */,
+ 0x0146 /* at */,
+ 0x0153 /* A */,
+ 0x015e /* B */,
+ 0x0169 /* C */,
+ 0x0174 /* D */,
+ 0x017f /* E */,
+ 0x018a /* F */,
+ 0x0195 /* G */,
+ 0x01a0 /* H */,
+ 0x01ab /* I */,
+ 0x01b6 /* J */,
+ 0x01c1 /* K */,
+ 0x01cc /* L */,
+ 0x01d7 /* M */,
+ 0x01e2 /* N */,
+ 0x01ed /* O */,
+ 0x01f8 /* P */,
+ 0x0203 /* Q */,
+ 0x020f /* R */,
+ 0x021a /* S */,
+ 0x0225 /* T */,
+ 0x0230 /* U */,
+ 0x023b /* V */,
+ 0x0246 /* W */,
+ 0x0251 /* X */,
+ 0x025c /* Y */,
+ 0x0267 /* Z */,
+ 0x0272 /* bracketleft */,
+ 0x027d /* backslash */,
+ 0x0288 /* bracketright */,
+ 0x0293 /* asciicircum */,
+ 0x029a /* underscore */,
+ 0x02a0 /* grave */,
+ 0x02a7 /* a */,
+ 0x02b0 /* b */,
+ 0x02bb /* c */,
+ 0x02c4 /* d */,
+ 0x02cf /* e */,
+ 0x02d8 /* f */,
+ 0x02e3 /* g */,
+ 0x02ed /* h */,
+ 0x02f8 /* i */,
+ 0x0303 /* j */,
+ 0x030f /* k */,
+ 0x031a /* l */,
+ 0x0325 /* m */,
+ 0x032e /* n */,
+ 0x0337 /* o */,
+ 0x0340 /* p */,
+ 0x034a /* q */,
+ 0x0354 /* r */,
+ 0x035d /* s */,
+ 0x0366 /* t */,
+ 0x0371 /* u */,
+ 0x037a /* v */,
+ 0x0383 /* w */,
+ 0x038c /* x */,
+ 0x0395 /* y */,
+ 0x039f /* z */,
+ 0x03a8 /* braceleft */,
+ 0x03b4 /* bar */,
+ 0x03bf /* braceright */,
+ 0x03cb /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_5x8 = {
+ .height = 8,
+ .ascent = 7,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_5x8_data,
+ .charoffs = font_5x8_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/c64.c b/Src/osmolib/src/target/firmware/fb/c64.c
new file mode 100644
index 0000000..82ebfa3
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/c64.c
@@ -0,0 +1,1069 @@
+#include <fb/font.h>
+static const uint8_t font_c64_data[] = {
+/* --- new character ' ' (32) starting at offset 0x0000 --- */
+ /*0000:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+ /*0006:*/ 0x00, /* ........ */
+ /*0007:*/ 0x00, /* ........ */
+ /*0008:*/ 0x00, /* ........ */
+ /*0009:*/ 0x00, /* ........ */
+ /*000a:*/ 0x00, /* ........ */
+ /*000b:*/ 0x00, /* ........ */
+ /*000c:*/ 0x00, /* ........ */
+/* --- new character '!' (33) starting at offset 0x000d --- */
+ /*000d:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0012:*/ 0x18, /* ...##... */
+ /*0013:*/ 0x18, /* ...##... */
+ /*0014:*/ 0x18, /* ...##... */
+ /*0015:*/ 0x18, /* ...##... */
+ /*0016:*/ 0x00, /* ........ */
+ /*0017:*/ 0x00, /* ........ */
+ /*0018:*/ 0x18, /* ...##... */
+ /*0019:*/ 0x00, /* ........ */
+/* --- new character '"' (34) starting at offset 0x001a --- */
+ /*001a:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*001f:*/ 0x66, /* .##..##. */
+ /*0020:*/ 0x66, /* .##..##. */
+ /*0021:*/ 0x66, /* .##..##. */
+ /*0022:*/ 0x00, /* ........ */
+ /*0023:*/ 0x00, /* ........ */
+ /*0024:*/ 0x00, /* ........ */
+ /*0025:*/ 0x00, /* ........ */
+ /*0026:*/ 0x00, /* ........ */
+/* --- new character '#' (35) starting at offset 0x0027 --- */
+ /*0027:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*002c:*/ 0x66, /* .##..##. */
+ /*002d:*/ 0x66, /* .##..##. */
+ /*002e:*/ 0xff, /* ######## */
+ /*002f:*/ 0x66, /* .##..##. */
+ /*0030:*/ 0xff, /* ######## */
+ /*0031:*/ 0x66, /* .##..##. */
+ /*0032:*/ 0x66, /* .##..##. */
+ /*0033:*/ 0x00, /* ........ */
+/* --- new character '$' (36) starting at offset 0x0034 --- */
+ /*0034:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0039:*/ 0x18, /* ...##... */
+ /*003a:*/ 0x3e, /* ..#####. */
+ /*003b:*/ 0x60, /* .##..... */
+ /*003c:*/ 0x3c, /* ..####.. */
+ /*003d:*/ 0x06, /* .....##. */
+ /*003e:*/ 0x7c, /* .#####.. */
+ /*003f:*/ 0x18, /* ...##... */
+ /*0040:*/ 0x00, /* ........ */
+/* --- new character '%' (37) starting at offset 0x0041 --- */
+ /*0041:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0046:*/ 0x62, /* .##...#. */
+ /*0047:*/ 0x66, /* .##..##. */
+ /*0048:*/ 0x0c, /* ....##.. */
+ /*0049:*/ 0x18, /* ...##... */
+ /*004a:*/ 0x30, /* ..##.... */
+ /*004b:*/ 0x66, /* .##..##. */
+ /*004c:*/ 0x46, /* .#...##. */
+ /*004d:*/ 0x00, /* ........ */
+/* --- new character '&' (38) starting at offset 0x004e --- */
+ /*004e:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0053:*/ 0x3c, /* ..####.. */
+ /*0054:*/ 0x66, /* .##..##. */
+ /*0055:*/ 0x3c, /* ..####.. */
+ /*0056:*/ 0x38, /* ..###... */
+ /*0057:*/ 0x67, /* .##..### */
+ /*0058:*/ 0x66, /* .##..##. */
+ /*0059:*/ 0x3f, /* ..###### */
+ /*005a:*/ 0x00, /* ........ */
+/* --- new character ''' (39) starting at offset 0x005b --- */
+ /*005b:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0060:*/ 0x06, /* .....##. */
+ /*0061:*/ 0x0c, /* ....##.. */
+ /*0062:*/ 0x18, /* ...##... */
+ /*0063:*/ 0x00, /* ........ */
+ /*0064:*/ 0x00, /* ........ */
+ /*0065:*/ 0x00, /* ........ */
+ /*0066:*/ 0x00, /* ........ */
+ /*0067:*/ 0x00, /* ........ */
+/* --- new character '(' (40) starting at offset 0x0068 --- */
+ /*0068:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*006d:*/ 0x0c, /* ....##.. */
+ /*006e:*/ 0x18, /* ...##... */
+ /*006f:*/ 0x30, /* ..##.... */
+ /*0070:*/ 0x30, /* ..##.... */
+ /*0071:*/ 0x30, /* ..##.... */
+ /*0072:*/ 0x18, /* ...##... */
+ /*0073:*/ 0x0c, /* ....##.. */
+ /*0074:*/ 0x00, /* ........ */
+/* --- new character ')' (41) starting at offset 0x0075 --- */
+ /*0075:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*007a:*/ 0x30, /* ..##.... */
+ /*007b:*/ 0x18, /* ...##... */
+ /*007c:*/ 0x0c, /* ....##.. */
+ /*007d:*/ 0x0c, /* ....##.. */
+ /*007e:*/ 0x0c, /* ....##.. */
+ /*007f:*/ 0x18, /* ...##... */
+ /*0080:*/ 0x30, /* ..##.... */
+ /*0081:*/ 0x00, /* ........ */
+/* --- new character '*' (42) starting at offset 0x0082 --- */
+ /*0082:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0087:*/ 0x00, /* ........ */
+ /*0088:*/ 0x66, /* .##..##. */
+ /*0089:*/ 0x3c, /* ..####.. */
+ /*008a:*/ 0xff, /* ######## */
+ /*008b:*/ 0x3c, /* ..####.. */
+ /*008c:*/ 0x66, /* .##..##. */
+ /*008d:*/ 0x00, /* ........ */
+ /*008e:*/ 0x00, /* ........ */
+/* --- new character '+' (43) starting at offset 0x008f --- */
+ /*008f:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0094:*/ 0x00, /* ........ */
+ /*0095:*/ 0x18, /* ...##... */
+ /*0096:*/ 0x18, /* ...##... */
+ /*0097:*/ 0x7e, /* .######. */
+ /*0098:*/ 0x18, /* ...##... */
+ /*0099:*/ 0x18, /* ...##... */
+ /*009a:*/ 0x00, /* ........ */
+ /*009b:*/ 0x00, /* ........ */
+/* --- new character ',' (44) starting at offset 0x009c --- */
+ /*009c:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00a1:*/ 0x00, /* ........ */
+ /*00a2:*/ 0x00, /* ........ */
+ /*00a3:*/ 0x00, /* ........ */
+ /*00a4:*/ 0x00, /* ........ */
+ /*00a5:*/ 0x00, /* ........ */
+ /*00a6:*/ 0x18, /* ...##... */
+ /*00a7:*/ 0x18, /* ...##... */
+ /*00a8:*/ 0x30, /* ..##.... */
+/* --- new character '-' (45) starting at offset 0x00a9 --- */
+ /*00a9:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00ae:*/ 0x00, /* ........ */
+ /*00af:*/ 0x00, /* ........ */
+ /*00b0:*/ 0x00, /* ........ */
+ /*00b1:*/ 0x7e, /* .######. */
+ /*00b2:*/ 0x00, /* ........ */
+ /*00b3:*/ 0x00, /* ........ */
+ /*00b4:*/ 0x00, /* ........ */
+ /*00b5:*/ 0x00, /* ........ */
+/* --- new character '.' (46) starting at offset 0x00b6 --- */
+ /*00b6:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00bb:*/ 0x00, /* ........ */
+ /*00bc:*/ 0x00, /* ........ */
+ /*00bd:*/ 0x00, /* ........ */
+ /*00be:*/ 0x00, /* ........ */
+ /*00bf:*/ 0x00, /* ........ */
+ /*00c0:*/ 0x18, /* ...##... */
+ /*00c1:*/ 0x18, /* ...##... */
+ /*00c2:*/ 0x00, /* ........ */
+/* --- new character '/' (47) starting at offset 0x00c3 --- */
+ /*00c3:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00c8:*/ 0x00, /* ........ */
+ /*00c9:*/ 0x03, /* ......## */
+ /*00ca:*/ 0x06, /* .....##. */
+ /*00cb:*/ 0x0c, /* ....##.. */
+ /*00cc:*/ 0x18, /* ...##... */
+ /*00cd:*/ 0x30, /* ..##.... */
+ /*00ce:*/ 0x60, /* .##..... */
+ /*00cf:*/ 0x00, /* ........ */
+/* --- new character '0' (48) starting at offset 0x00d0 --- */
+ /*00d0:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00d5:*/ 0x3c, /* ..####.. */
+ /*00d6:*/ 0x66, /* .##..##. */
+ /*00d7:*/ 0x6e, /* .##.###. */
+ /*00d8:*/ 0x76, /* .###.##. */
+ /*00d9:*/ 0x66, /* .##..##. */
+ /*00da:*/ 0x66, /* .##..##. */
+ /*00db:*/ 0x3c, /* ..####.. */
+ /*00dc:*/ 0x00, /* ........ */
+/* --- new character '1' (49) starting at offset 0x00dd --- */
+ /*00dd:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00e2:*/ 0x18, /* ...##... */
+ /*00e3:*/ 0x18, /* ...##... */
+ /*00e4:*/ 0x38, /* ..###... */
+ /*00e5:*/ 0x18, /* ...##... */
+ /*00e6:*/ 0x18, /* ...##... */
+ /*00e7:*/ 0x18, /* ...##... */
+ /*00e8:*/ 0x7e, /* .######. */
+ /*00e9:*/ 0x00, /* ........ */
+/* --- new character '2' (50) starting at offset 0x00ea --- */
+ /*00ea:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00ef:*/ 0x3c, /* ..####.. */
+ /*00f0:*/ 0x66, /* .##..##. */
+ /*00f1:*/ 0x06, /* .....##. */
+ /*00f2:*/ 0x0c, /* ....##.. */
+ /*00f3:*/ 0x30, /* ..##.... */
+ /*00f4:*/ 0x60, /* .##..... */
+ /*00f5:*/ 0x7e, /* .######. */
+ /*00f6:*/ 0x00, /* ........ */
+/* --- new character '3' (51) starting at offset 0x00f7 --- */
+ /*00f7:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00fc:*/ 0x3c, /* ..####.. */
+ /*00fd:*/ 0x66, /* .##..##. */
+ /*00fe:*/ 0x06, /* .....##. */
+ /*00ff:*/ 0x1c, /* ...###.. */
+ /*0100:*/ 0x06, /* .....##. */
+ /*0101:*/ 0x66, /* .##..##. */
+ /*0102:*/ 0x3c, /* ..####.. */
+ /*0103:*/ 0x00, /* ........ */
+/* --- new character '4' (52) starting at offset 0x0104 --- */
+ /*0104:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0109:*/ 0x06, /* .....##. */
+ /*010a:*/ 0x0e, /* ....###. */
+ /*010b:*/ 0x1e, /* ...####. */
+ /*010c:*/ 0x66, /* .##..##. */
+ /*010d:*/ 0x7f, /* .####### */
+ /*010e:*/ 0x06, /* .....##. */
+ /*010f:*/ 0x06, /* .....##. */
+ /*0110:*/ 0x00, /* ........ */
+/* --- new character '5' (53) starting at offset 0x0111 --- */
+ /*0111:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0116:*/ 0x7e, /* .######. */
+ /*0117:*/ 0x60, /* .##..... */
+ /*0118:*/ 0x7c, /* .#####.. */
+ /*0119:*/ 0x06, /* .....##. */
+ /*011a:*/ 0x06, /* .....##. */
+ /*011b:*/ 0x66, /* .##..##. */
+ /*011c:*/ 0x3c, /* ..####.. */
+ /*011d:*/ 0x00, /* ........ */
+/* --- new character '6' (54) starting at offset 0x011e --- */
+ /*011e:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0123:*/ 0x3c, /* ..####.. */
+ /*0124:*/ 0x66, /* .##..##. */
+ /*0125:*/ 0x60, /* .##..... */
+ /*0126:*/ 0x7c, /* .#####.. */
+ /*0127:*/ 0x66, /* .##..##. */
+ /*0128:*/ 0x66, /* .##..##. */
+ /*0129:*/ 0x3c, /* ..####.. */
+ /*012a:*/ 0x00, /* ........ */
+/* --- new character '7' (55) starting at offset 0x012b --- */
+ /*012b:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0130:*/ 0x7e, /* .######. */
+ /*0131:*/ 0x66, /* .##..##. */
+ /*0132:*/ 0x0c, /* ....##.. */
+ /*0133:*/ 0x18, /* ...##... */
+ /*0134:*/ 0x18, /* ...##... */
+ /*0135:*/ 0x18, /* ...##... */
+ /*0136:*/ 0x18, /* ...##... */
+ /*0137:*/ 0x00, /* ........ */
+/* --- new character '8' (56) starting at offset 0x0138 --- */
+ /*0138:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*013d:*/ 0x3c, /* ..####.. */
+ /*013e:*/ 0x66, /* .##..##. */
+ /*013f:*/ 0x66, /* .##..##. */
+ /*0140:*/ 0x3c, /* ..####.. */
+ /*0141:*/ 0x66, /* .##..##. */
+ /*0142:*/ 0x66, /* .##..##. */
+ /*0143:*/ 0x3c, /* ..####.. */
+ /*0144:*/ 0x00, /* ........ */
+/* --- new character '9' (57) starting at offset 0x0145 --- */
+ /*0145:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*014a:*/ 0x3c, /* ..####.. */
+ /*014b:*/ 0x66, /* .##..##. */
+ /*014c:*/ 0x66, /* .##..##. */
+ /*014d:*/ 0x3e, /* ..#####. */
+ /*014e:*/ 0x06, /* .....##. */
+ /*014f:*/ 0x66, /* .##..##. */
+ /*0150:*/ 0x3c, /* ..####.. */
+ /*0151:*/ 0x00, /* ........ */
+/* --- new character ':' (58) starting at offset 0x0152 --- */
+ /*0152:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0157:*/ 0x00, /* ........ */
+ /*0158:*/ 0x00, /* ........ */
+ /*0159:*/ 0x18, /* ...##... */
+ /*015a:*/ 0x00, /* ........ */
+ /*015b:*/ 0x00, /* ........ */
+ /*015c:*/ 0x18, /* ...##... */
+ /*015d:*/ 0x00, /* ........ */
+ /*015e:*/ 0x00, /* ........ */
+/* --- new character ';' (59) starting at offset 0x015f --- */
+ /*015f:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0164:*/ 0x00, /* ........ */
+ /*0165:*/ 0x00, /* ........ */
+ /*0166:*/ 0x18, /* ...##... */
+ /*0167:*/ 0x00, /* ........ */
+ /*0168:*/ 0x00, /* ........ */
+ /*0169:*/ 0x18, /* ...##... */
+ /*016a:*/ 0x18, /* ...##... */
+ /*016b:*/ 0x30, /* ..##.... */
+/* --- new character '<' (60) starting at offset 0x016c --- */
+ /*016c:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0171:*/ 0x0e, /* ....###. */
+ /*0172:*/ 0x18, /* ...##... */
+ /*0173:*/ 0x30, /* ..##.... */
+ /*0174:*/ 0x60, /* .##..... */
+ /*0175:*/ 0x30, /* ..##.... */
+ /*0176:*/ 0x18, /* ...##... */
+ /*0177:*/ 0x0e, /* ....###. */
+ /*0178:*/ 0x00, /* ........ */
+/* --- new character '=' (61) starting at offset 0x0179 --- */
+ /*0179:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*017e:*/ 0x00, /* ........ */
+ /*017f:*/ 0x00, /* ........ */
+ /*0180:*/ 0x7e, /* .######. */
+ /*0181:*/ 0x00, /* ........ */
+ /*0182:*/ 0x7e, /* .######. */
+ /*0183:*/ 0x00, /* ........ */
+ /*0184:*/ 0x00, /* ........ */
+ /*0185:*/ 0x00, /* ........ */
+/* --- new character '>' (62) starting at offset 0x0186 --- */
+ /*0186:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*018b:*/ 0x70, /* .###.... */
+ /*018c:*/ 0x18, /* ...##... */
+ /*018d:*/ 0x0c, /* ....##.. */
+ /*018e:*/ 0x06, /* .....##. */
+ /*018f:*/ 0x0c, /* ....##.. */
+ /*0190:*/ 0x18, /* ...##... */
+ /*0191:*/ 0x70, /* .###.... */
+ /*0192:*/ 0x00, /* ........ */
+/* --- new character '?' (63) starting at offset 0x0193 --- */
+ /*0193:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0198:*/ 0x3c, /* ..####.. */
+ /*0199:*/ 0x66, /* .##..##. */
+ /*019a:*/ 0x06, /* .....##. */
+ /*019b:*/ 0x0c, /* ....##.. */
+ /*019c:*/ 0x18, /* ...##... */
+ /*019d:*/ 0x00, /* ........ */
+ /*019e:*/ 0x18, /* ...##... */
+ /*019f:*/ 0x00, /* ........ */
+/* --- new character '@' (64) starting at offset 0x01a0 --- */
+ /*01a0:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01a5:*/ 0x3c, /* ..####.. */
+ /*01a6:*/ 0x66, /* .##..##. */
+ /*01a7:*/ 0x6e, /* .##.###. */
+ /*01a8:*/ 0x6e, /* .##.###. */
+ /*01a9:*/ 0x60, /* .##..... */
+ /*01aa:*/ 0x62, /* .##...#. */
+ /*01ab:*/ 0x3c, /* ..####.. */
+ /*01ac:*/ 0x00, /* ........ */
+/* --- new character 'A' (65) starting at offset 0x01ad --- */
+ /*01ad:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01b2:*/ 0x18, /* ...##... */
+ /*01b3:*/ 0x3c, /* ..####.. */
+ /*01b4:*/ 0x66, /* .##..##. */
+ /*01b5:*/ 0x7e, /* .######. */
+ /*01b6:*/ 0x66, /* .##..##. */
+ /*01b7:*/ 0x66, /* .##..##. */
+ /*01b8:*/ 0x66, /* .##..##. */
+ /*01b9:*/ 0x00, /* ........ */
+/* --- new character 'B' (66) starting at offset 0x01ba --- */
+ /*01ba:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01bf:*/ 0x7c, /* .#####.. */
+ /*01c0:*/ 0x66, /* .##..##. */
+ /*01c1:*/ 0x66, /* .##..##. */
+ /*01c2:*/ 0x7c, /* .#####.. */
+ /*01c3:*/ 0x66, /* .##..##. */
+ /*01c4:*/ 0x66, /* .##..##. */
+ /*01c5:*/ 0x7c, /* .#####.. */
+ /*01c6:*/ 0x00, /* ........ */
+/* --- new character 'C' (67) starting at offset 0x01c7 --- */
+ /*01c7:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01cc:*/ 0x3c, /* ..####.. */
+ /*01cd:*/ 0x66, /* .##..##. */
+ /*01ce:*/ 0x60, /* .##..... */
+ /*01cf:*/ 0x60, /* .##..... */
+ /*01d0:*/ 0x60, /* .##..... */
+ /*01d1:*/ 0x66, /* .##..##. */
+ /*01d2:*/ 0x3c, /* ..####.. */
+ /*01d3:*/ 0x00, /* ........ */
+/* --- new character 'D' (68) starting at offset 0x01d4 --- */
+ /*01d4:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01d9:*/ 0x78, /* .####... */
+ /*01da:*/ 0x6c, /* .##.##.. */
+ /*01db:*/ 0x66, /* .##..##. */
+ /*01dc:*/ 0x66, /* .##..##. */
+ /*01dd:*/ 0x66, /* .##..##. */
+ /*01de:*/ 0x6c, /* .##.##.. */
+ /*01df:*/ 0x78, /* .####... */
+ /*01e0:*/ 0x00, /* ........ */
+/* --- new character 'E' (69) starting at offset 0x01e1 --- */
+ /*01e1:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01e6:*/ 0x7e, /* .######. */
+ /*01e7:*/ 0x60, /* .##..... */
+ /*01e8:*/ 0x60, /* .##..... */
+ /*01e9:*/ 0x78, /* .####... */
+ /*01ea:*/ 0x60, /* .##..... */
+ /*01eb:*/ 0x60, /* .##..... */
+ /*01ec:*/ 0x7e, /* .######. */
+ /*01ed:*/ 0x00, /* ........ */
+/* --- new character 'F' (70) starting at offset 0x01ee --- */
+ /*01ee:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01f3:*/ 0x7e, /* .######. */
+ /*01f4:*/ 0x60, /* .##..... */
+ /*01f5:*/ 0x60, /* .##..... */
+ /*01f6:*/ 0x78, /* .####... */
+ /*01f7:*/ 0x60, /* .##..... */
+ /*01f8:*/ 0x60, /* .##..... */
+ /*01f9:*/ 0x60, /* .##..... */
+ /*01fa:*/ 0x00, /* ........ */
+/* --- new character 'G' (71) starting at offset 0x01fb --- */
+ /*01fb:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0200:*/ 0x3c, /* ..####.. */
+ /*0201:*/ 0x66, /* .##..##. */
+ /*0202:*/ 0x60, /* .##..... */
+ /*0203:*/ 0x6e, /* .##.###. */
+ /*0204:*/ 0x66, /* .##..##. */
+ /*0205:*/ 0x66, /* .##..##. */
+ /*0206:*/ 0x3c, /* ..####.. */
+ /*0207:*/ 0x00, /* ........ */
+/* --- new character 'H' (72) starting at offset 0x0208 --- */
+ /*0208:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*020d:*/ 0x66, /* .##..##. */
+ /*020e:*/ 0x66, /* .##..##. */
+ /*020f:*/ 0x66, /* .##..##. */
+ /*0210:*/ 0x7e, /* .######. */
+ /*0211:*/ 0x66, /* .##..##. */
+ /*0212:*/ 0x66, /* .##..##. */
+ /*0213:*/ 0x66, /* .##..##. */
+ /*0214:*/ 0x00, /* ........ */
+/* --- new character 'I' (73) starting at offset 0x0215 --- */
+ /*0215:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*021a:*/ 0x3c, /* ..####.. */
+ /*021b:*/ 0x18, /* ...##... */
+ /*021c:*/ 0x18, /* ...##... */
+ /*021d:*/ 0x18, /* ...##... */
+ /*021e:*/ 0x18, /* ...##... */
+ /*021f:*/ 0x18, /* ...##... */
+ /*0220:*/ 0x3c, /* ..####.. */
+ /*0221:*/ 0x00, /* ........ */
+/* --- new character 'J' (74) starting at offset 0x0222 --- */
+ /*0222:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0227:*/ 0x1e, /* ...####. */
+ /*0228:*/ 0x0c, /* ....##.. */
+ /*0229:*/ 0x0c, /* ....##.. */
+ /*022a:*/ 0x0c, /* ....##.. */
+ /*022b:*/ 0x0c, /* ....##.. */
+ /*022c:*/ 0x6c, /* .##.##.. */
+ /*022d:*/ 0x38, /* ..###... */
+ /*022e:*/ 0x00, /* ........ */
+/* --- new character 'K' (75) starting at offset 0x022f --- */
+ /*022f:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0234:*/ 0x66, /* .##..##. */
+ /*0235:*/ 0x6c, /* .##.##.. */
+ /*0236:*/ 0x78, /* .####... */
+ /*0237:*/ 0x70, /* .###.... */
+ /*0238:*/ 0x78, /* .####... */
+ /*0239:*/ 0x6c, /* .##.##.. */
+ /*023a:*/ 0x66, /* .##..##. */
+ /*023b:*/ 0x00, /* ........ */
+/* --- new character 'L' (76) starting at offset 0x023c --- */
+ /*023c:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0241:*/ 0x60, /* .##..... */
+ /*0242:*/ 0x60, /* .##..... */
+ /*0243:*/ 0x60, /* .##..... */
+ /*0244:*/ 0x60, /* .##..... */
+ /*0245:*/ 0x60, /* .##..... */
+ /*0246:*/ 0x60, /* .##..... */
+ /*0247:*/ 0x7e, /* .######. */
+ /*0248:*/ 0x00, /* ........ */
+/* --- new character 'M' (77) starting at offset 0x0249 --- */
+ /*0249:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*024e:*/ 0x63, /* .##...## */
+ /*024f:*/ 0x77, /* .###.### */
+ /*0250:*/ 0x7f, /* .####### */
+ /*0251:*/ 0x6b, /* .##.#.## */
+ /*0252:*/ 0x63, /* .##...## */
+ /*0253:*/ 0x63, /* .##...## */
+ /*0254:*/ 0x63, /* .##...## */
+ /*0255:*/ 0x00, /* ........ */
+/* --- new character 'N' (78) starting at offset 0x0256 --- */
+ /*0256:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*025b:*/ 0x66, /* .##..##. */
+ /*025c:*/ 0x76, /* .###.##. */
+ /*025d:*/ 0x7e, /* .######. */
+ /*025e:*/ 0x7e, /* .######. */
+ /*025f:*/ 0x6e, /* .##.###. */
+ /*0260:*/ 0x66, /* .##..##. */
+ /*0261:*/ 0x66, /* .##..##. */
+ /*0262:*/ 0x00, /* ........ */
+/* --- new character 'O' (79) starting at offset 0x0263 --- */
+ /*0263:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0268:*/ 0x3c, /* ..####.. */
+ /*0269:*/ 0x66, /* .##..##. */
+ /*026a:*/ 0x66, /* .##..##. */
+ /*026b:*/ 0x66, /* .##..##. */
+ /*026c:*/ 0x66, /* .##..##. */
+ /*026d:*/ 0x66, /* .##..##. */
+ /*026e:*/ 0x3c, /* ..####.. */
+ /*026f:*/ 0x00, /* ........ */
+/* --- new character 'P' (80) starting at offset 0x0270 --- */
+ /*0270:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0275:*/ 0x7c, /* .#####.. */
+ /*0276:*/ 0x66, /* .##..##. */
+ /*0277:*/ 0x66, /* .##..##. */
+ /*0278:*/ 0x7c, /* .#####.. */
+ /*0279:*/ 0x60, /* .##..... */
+ /*027a:*/ 0x60, /* .##..... */
+ /*027b:*/ 0x60, /* .##..... */
+ /*027c:*/ 0x00, /* ........ */
+/* --- new character 'Q' (81) starting at offset 0x027d --- */
+ /*027d:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0282:*/ 0x3c, /* ..####.. */
+ /*0283:*/ 0x66, /* .##..##. */
+ /*0284:*/ 0x66, /* .##..##. */
+ /*0285:*/ 0x66, /* .##..##. */
+ /*0286:*/ 0x66, /* .##..##. */
+ /*0287:*/ 0x3c, /* ..####.. */
+ /*0288:*/ 0x0e, /* ....###. */
+ /*0289:*/ 0x00, /* ........ */
+/* --- new character 'R' (82) starting at offset 0x028a --- */
+ /*028a:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*028f:*/ 0x7c, /* .#####.. */
+ /*0290:*/ 0x66, /* .##..##. */
+ /*0291:*/ 0x66, /* .##..##. */
+ /*0292:*/ 0x7c, /* .#####.. */
+ /*0293:*/ 0x78, /* .####... */
+ /*0294:*/ 0x6c, /* .##.##.. */
+ /*0295:*/ 0x66, /* .##..##. */
+ /*0296:*/ 0x00, /* ........ */
+/* --- new character 'S' (83) starting at offset 0x0297 --- */
+ /*0297:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*029c:*/ 0x3c, /* ..####.. */
+ /*029d:*/ 0x66, /* .##..##. */
+ /*029e:*/ 0x60, /* .##..... */
+ /*029f:*/ 0x3c, /* ..####.. */
+ /*02a0:*/ 0x06, /* .....##. */
+ /*02a1:*/ 0x66, /* .##..##. */
+ /*02a2:*/ 0x3c, /* ..####.. */
+ /*02a3:*/ 0x00, /* ........ */
+/* --- new character 'T' (84) starting at offset 0x02a4 --- */
+ /*02a4:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02a9:*/ 0x7e, /* .######. */
+ /*02aa:*/ 0x18, /* ...##... */
+ /*02ab:*/ 0x18, /* ...##... */
+ /*02ac:*/ 0x18, /* ...##... */
+ /*02ad:*/ 0x18, /* ...##... */
+ /*02ae:*/ 0x18, /* ...##... */
+ /*02af:*/ 0x18, /* ...##... */
+ /*02b0:*/ 0x00, /* ........ */
+/* --- new character 'U' (85) starting at offset 0x02b1 --- */
+ /*02b1:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02b6:*/ 0x66, /* .##..##. */
+ /*02b7:*/ 0x66, /* .##..##. */
+ /*02b8:*/ 0x66, /* .##..##. */
+ /*02b9:*/ 0x66, /* .##..##. */
+ /*02ba:*/ 0x66, /* .##..##. */
+ /*02bb:*/ 0x66, /* .##..##. */
+ /*02bc:*/ 0x3c, /* ..####.. */
+ /*02bd:*/ 0x00, /* ........ */
+/* --- new character 'V' (86) starting at offset 0x02be --- */
+ /*02be:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02c3:*/ 0x66, /* .##..##. */
+ /*02c4:*/ 0x66, /* .##..##. */
+ /*02c5:*/ 0x66, /* .##..##. */
+ /*02c6:*/ 0x66, /* .##..##. */
+ /*02c7:*/ 0x66, /* .##..##. */
+ /*02c8:*/ 0x3c, /* ..####.. */
+ /*02c9:*/ 0x18, /* ...##... */
+ /*02ca:*/ 0x00, /* ........ */
+/* --- new character 'W' (87) starting at offset 0x02cb --- */
+ /*02cb:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02d0:*/ 0x63, /* .##...## */
+ /*02d1:*/ 0x63, /* .##...## */
+ /*02d2:*/ 0x63, /* .##...## */
+ /*02d3:*/ 0x6b, /* .##.#.## */
+ /*02d4:*/ 0x7f, /* .####### */
+ /*02d5:*/ 0x77, /* .###.### */
+ /*02d6:*/ 0x63, /* .##...## */
+ /*02d7:*/ 0x00, /* ........ */
+/* --- new character 'X' (88) starting at offset 0x02d8 --- */
+ /*02d8:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02dd:*/ 0x66, /* .##..##. */
+ /*02de:*/ 0x66, /* .##..##. */
+ /*02df:*/ 0x3c, /* ..####.. */
+ /*02e0:*/ 0x18, /* ...##... */
+ /*02e1:*/ 0x3c, /* ..####.. */
+ /*02e2:*/ 0x66, /* .##..##. */
+ /*02e3:*/ 0x66, /* .##..##. */
+ /*02e4:*/ 0x00, /* ........ */
+/* --- new character 'Y' (89) starting at offset 0x02e5 --- */
+ /*02e5:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02ea:*/ 0x66, /* .##..##. */
+ /*02eb:*/ 0x66, /* .##..##. */
+ /*02ec:*/ 0x66, /* .##..##. */
+ /*02ed:*/ 0x3c, /* ..####.. */
+ /*02ee:*/ 0x18, /* ...##... */
+ /*02ef:*/ 0x18, /* ...##... */
+ /*02f0:*/ 0x18, /* ...##... */
+ /*02f1:*/ 0x00, /* ........ */
+/* --- new character 'Z' (90) starting at offset 0x02f2 --- */
+ /*02f2:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02f7:*/ 0x7e, /* .######. */
+ /*02f8:*/ 0x06, /* .....##. */
+ /*02f9:*/ 0x0c, /* ....##.. */
+ /*02fa:*/ 0x18, /* ...##... */
+ /*02fb:*/ 0x30, /* ..##.... */
+ /*02fc:*/ 0x60, /* .##..... */
+ /*02fd:*/ 0x7e, /* .######. */
+ /*02fe:*/ 0x00, /* ........ */
+/* --- new character '[' (91) starting at offset 0x02ff --- */
+ /*02ff:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0304:*/ 0x3c, /* ..####.. */
+ /*0305:*/ 0x30, /* ..##.... */
+ /*0306:*/ 0x30, /* ..##.... */
+ /*0307:*/ 0x30, /* ..##.... */
+ /*0308:*/ 0x30, /* ..##.... */
+ /*0309:*/ 0x30, /* ..##.... */
+ /*030a:*/ 0x3c, /* ..####.. */
+ /*030b:*/ 0x00, /* ........ */
+/* --- new character '\' (92) starting at offset 0x030c --- */
+ /*030c:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0311:*/ 0x00, /* ........ */
+ /*0312:*/ 0xc0, /* ##...... */
+ /*0313:*/ 0x60, /* .##..... */
+ /*0314:*/ 0x30, /* ..##.... */
+ /*0315:*/ 0x18, /* ...##... */
+ /*0316:*/ 0x0c, /* ....##.. */
+ /*0317:*/ 0x06, /* .....##. */
+ /*0318:*/ 0x00, /* ........ */
+/* --- new character ']' (93) starting at offset 0x0319 --- */
+ /*0319:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*031e:*/ 0x3c, /* ..####.. */
+ /*031f:*/ 0x0c, /* ....##.. */
+ /*0320:*/ 0x0c, /* ....##.. */
+ /*0321:*/ 0x0c, /* ....##.. */
+ /*0322:*/ 0x0c, /* ....##.. */
+ /*0323:*/ 0x0c, /* ....##.. */
+ /*0324:*/ 0x3c, /* ..####.. */
+ /*0325:*/ 0x00, /* ........ */
+/* --- new character '^' (94) starting at offset 0x0326 --- */
+ /*0326:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*032b:*/ 0x18, /* ...##... */
+ /*032c:*/ 0x3c, /* ..####.. */
+ /*032d:*/ 0x66, /* .##..##. */
+ /*032e:*/ 0x00, /* ........ */
+ /*032f:*/ 0x00, /* ........ */
+ /*0330:*/ 0x00, /* ........ */
+ /*0331:*/ 0x00, /* ........ */
+ /*0332:*/ 0x00, /* ........ */
+/* --- new character '_' (95) starting at offset 0x0333 --- */
+ /*0333:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0338:*/ 0x00, /* ........ */
+ /*0339:*/ 0x00, /* ........ */
+ /*033a:*/ 0x00, /* ........ */
+ /*033b:*/ 0x00, /* ........ */
+ /*033c:*/ 0x00, /* ........ */
+ /*033d:*/ 0x00, /* ........ */
+ /*033e:*/ 0x00, /* ........ */
+ /*033f:*/ 0xff, /* ######## */
+/* --- new character '`' (96) starting at offset 0x0340 --- */
+ /*0340:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0345:*/ 0x60, /* .##..... */
+ /*0346:*/ 0x30, /* ..##.... */
+ /*0347:*/ 0x18, /* ...##... */
+ /*0348:*/ 0x00, /* ........ */
+ /*0349:*/ 0x00, /* ........ */
+ /*034a:*/ 0x00, /* ........ */
+ /*034b:*/ 0x00, /* ........ */
+ /*034c:*/ 0x00, /* ........ */
+/* --- new character 'a' (97) starting at offset 0x034d --- */
+ /*034d:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0352:*/ 0x00, /* ........ */
+ /*0353:*/ 0x00, /* ........ */
+ /*0354:*/ 0x3c, /* ..####.. */
+ /*0355:*/ 0x06, /* .....##. */
+ /*0356:*/ 0x3e, /* ..#####. */
+ /*0357:*/ 0x66, /* .##..##. */
+ /*0358:*/ 0x3e, /* ..#####. */
+ /*0359:*/ 0x00, /* ........ */
+/* --- new character 'b' (98) starting at offset 0x035a --- */
+ /*035a:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*035f:*/ 0x00, /* ........ */
+ /*0360:*/ 0x60, /* .##..... */
+ /*0361:*/ 0x60, /* .##..... */
+ /*0362:*/ 0x7c, /* .#####.. */
+ /*0363:*/ 0x66, /* .##..##. */
+ /*0364:*/ 0x66, /* .##..##. */
+ /*0365:*/ 0x7c, /* .#####.. */
+ /*0366:*/ 0x00, /* ........ */
+/* --- new character 'c' (99) starting at offset 0x0367 --- */
+ /*0367:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*036c:*/ 0x00, /* ........ */
+ /*036d:*/ 0x00, /* ........ */
+ /*036e:*/ 0x3c, /* ..####.. */
+ /*036f:*/ 0x60, /* .##..... */
+ /*0370:*/ 0x60, /* .##..... */
+ /*0371:*/ 0x60, /* .##..... */
+ /*0372:*/ 0x3c, /* ..####.. */
+ /*0373:*/ 0x00, /* ........ */
+/* --- new character 'd' (100) starting at offset 0x0374 --- */
+ /*0374:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0379:*/ 0x00, /* ........ */
+ /*037a:*/ 0x06, /* .....##. */
+ /*037b:*/ 0x06, /* .....##. */
+ /*037c:*/ 0x3e, /* ..#####. */
+ /*037d:*/ 0x66, /* .##..##. */
+ /*037e:*/ 0x66, /* .##..##. */
+ /*037f:*/ 0x3e, /* ..#####. */
+ /*0380:*/ 0x00, /* ........ */
+/* --- new character 'e' (101) starting at offset 0x0381 --- */
+ /*0381:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0386:*/ 0x00, /* ........ */
+ /*0387:*/ 0x00, /* ........ */
+ /*0388:*/ 0x3c, /* ..####.. */
+ /*0389:*/ 0x66, /* .##..##. */
+ /*038a:*/ 0x7e, /* .######. */
+ /*038b:*/ 0x60, /* .##..... */
+ /*038c:*/ 0x3c, /* ..####.. */
+ /*038d:*/ 0x00, /* ........ */
+/* --- new character 'f' (102) starting at offset 0x038e --- */
+ /*038e:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0393:*/ 0x00, /* ........ */
+ /*0394:*/ 0x0e, /* ....###. */
+ /*0395:*/ 0x18, /* ...##... */
+ /*0396:*/ 0x3e, /* ..#####. */
+ /*0397:*/ 0x18, /* ...##... */
+ /*0398:*/ 0x18, /* ...##... */
+ /*0399:*/ 0x18, /* ...##... */
+ /*039a:*/ 0x00, /* ........ */
+/* --- new character 'g' (103) starting at offset 0x039b --- */
+ /*039b:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03a0:*/ 0x00, /* ........ */
+ /*03a1:*/ 0x00, /* ........ */
+ /*03a2:*/ 0x3e, /* ..#####. */
+ /*03a3:*/ 0x66, /* .##..##. */
+ /*03a4:*/ 0x66, /* .##..##. */
+ /*03a5:*/ 0x3e, /* ..#####. */
+ /*03a6:*/ 0x06, /* .....##. */
+ /*03a7:*/ 0x7c, /* .#####.. */
+/* --- new character 'h' (104) starting at offset 0x03a8 --- */
+ /*03a8:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03ad:*/ 0x00, /* ........ */
+ /*03ae:*/ 0x60, /* .##..... */
+ /*03af:*/ 0x60, /* .##..... */
+ /*03b0:*/ 0x7c, /* .#####.. */
+ /*03b1:*/ 0x66, /* .##..##. */
+ /*03b2:*/ 0x66, /* .##..##. */
+ /*03b3:*/ 0x66, /* .##..##. */
+ /*03b4:*/ 0x00, /* ........ */
+/* --- new character 'i' (105) starting at offset 0x03b5 --- */
+ /*03b5:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03ba:*/ 0x00, /* ........ */
+ /*03bb:*/ 0x18, /* ...##... */
+ /*03bc:*/ 0x00, /* ........ */
+ /*03bd:*/ 0x38, /* ..###... */
+ /*03be:*/ 0x18, /* ...##... */
+ /*03bf:*/ 0x18, /* ...##... */
+ /*03c0:*/ 0x3c, /* ..####.. */
+ /*03c1:*/ 0x00, /* ........ */
+/* --- new character 'j' (106) starting at offset 0x03c2 --- */
+ /*03c2:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03c7:*/ 0x00, /* ........ */
+ /*03c8:*/ 0x06, /* .....##. */
+ /*03c9:*/ 0x00, /* ........ */
+ /*03ca:*/ 0x06, /* .....##. */
+ /*03cb:*/ 0x06, /* .....##. */
+ /*03cc:*/ 0x06, /* .....##. */
+ /*03cd:*/ 0x06, /* .....##. */
+ /*03ce:*/ 0x3c, /* ..####.. */
+/* --- new character 'k' (107) starting at offset 0x03cf --- */
+ /*03cf:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03d4:*/ 0x00, /* ........ */
+ /*03d5:*/ 0x60, /* .##..... */
+ /*03d6:*/ 0x60, /* .##..... */
+ /*03d7:*/ 0x6c, /* .##.##.. */
+ /*03d8:*/ 0x78, /* .####... */
+ /*03d9:*/ 0x6c, /* .##.##.. */
+ /*03da:*/ 0x66, /* .##..##. */
+ /*03db:*/ 0x00, /* ........ */
+/* --- new character 'l' (108) starting at offset 0x03dc --- */
+ /*03dc:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03e1:*/ 0x00, /* ........ */
+ /*03e2:*/ 0x38, /* ..###... */
+ /*03e3:*/ 0x18, /* ...##... */
+ /*03e4:*/ 0x18, /* ...##... */
+ /*03e5:*/ 0x18, /* ...##... */
+ /*03e6:*/ 0x18, /* ...##... */
+ /*03e7:*/ 0x3c, /* ..####.. */
+ /*03e8:*/ 0x00, /* ........ */
+/* --- new character 'm' (109) starting at offset 0x03e9 --- */
+ /*03e9:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03ee:*/ 0x00, /* ........ */
+ /*03ef:*/ 0x00, /* ........ */
+ /*03f0:*/ 0x66, /* .##..##. */
+ /*03f1:*/ 0x7f, /* .####### */
+ /*03f2:*/ 0x7f, /* .####### */
+ /*03f3:*/ 0x6b, /* .##.#.## */
+ /*03f4:*/ 0x63, /* .##...## */
+ /*03f5:*/ 0x00, /* ........ */
+/* --- new character 'n' (110) starting at offset 0x03f6 --- */
+ /*03f6:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03fb:*/ 0x00, /* ........ */
+ /*03fc:*/ 0x00, /* ........ */
+ /*03fd:*/ 0x7c, /* .#####.. */
+ /*03fe:*/ 0x66, /* .##..##. */
+ /*03ff:*/ 0x66, /* .##..##. */
+ /*0400:*/ 0x66, /* .##..##. */
+ /*0401:*/ 0x66, /* .##..##. */
+ /*0402:*/ 0x00, /* ........ */
+/* --- new character 'o' (111) starting at offset 0x0403 --- */
+ /*0403:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0408:*/ 0x00, /* ........ */
+ /*0409:*/ 0x00, /* ........ */
+ /*040a:*/ 0x3c, /* ..####.. */
+ /*040b:*/ 0x66, /* .##..##. */
+ /*040c:*/ 0x66, /* .##..##. */
+ /*040d:*/ 0x66, /* .##..##. */
+ /*040e:*/ 0x3c, /* ..####.. */
+ /*040f:*/ 0x00, /* ........ */
+/* --- new character 'p' (112) starting at offset 0x0410 --- */
+ /*0410:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0415:*/ 0x00, /* ........ */
+ /*0416:*/ 0x00, /* ........ */
+ /*0417:*/ 0x7c, /* .#####.. */
+ /*0418:*/ 0x66, /* .##..##. */
+ /*0419:*/ 0x66, /* .##..##. */
+ /*041a:*/ 0x7c, /* .#####.. */
+ /*041b:*/ 0x60, /* .##..... */
+ /*041c:*/ 0x60, /* .##..... */
+/* --- new character 'q' (113) starting at offset 0x041d --- */
+ /*041d:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0422:*/ 0x00, /* ........ */
+ /*0423:*/ 0x00, /* ........ */
+ /*0424:*/ 0x3e, /* ..#####. */
+ /*0425:*/ 0x66, /* .##..##. */
+ /*0426:*/ 0x66, /* .##..##. */
+ /*0427:*/ 0x3e, /* ..#####. */
+ /*0428:*/ 0x06, /* .....##. */
+ /*0429:*/ 0x06, /* .....##. */
+/* --- new character 'r' (114) starting at offset 0x042a --- */
+ /*042a:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*042f:*/ 0x00, /* ........ */
+ /*0430:*/ 0x00, /* ........ */
+ /*0431:*/ 0x7c, /* .#####.. */
+ /*0432:*/ 0x66, /* .##..##. */
+ /*0433:*/ 0x60, /* .##..... */
+ /*0434:*/ 0x60, /* .##..... */
+ /*0435:*/ 0x60, /* .##..... */
+ /*0436:*/ 0x00, /* ........ */
+/* --- new character 's' (115) starting at offset 0x0437 --- */
+ /*0437:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*043c:*/ 0x00, /* ........ */
+ /*043d:*/ 0x00, /* ........ */
+ /*043e:*/ 0x3e, /* ..#####. */
+ /*043f:*/ 0x60, /* .##..... */
+ /*0440:*/ 0x3c, /* ..####.. */
+ /*0441:*/ 0x06, /* .....##. */
+ /*0442:*/ 0x7c, /* .#####.. */
+ /*0443:*/ 0x00, /* ........ */
+/* --- new character 't' (116) starting at offset 0x0444 --- */
+ /*0444:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0449:*/ 0x00, /* ........ */
+ /*044a:*/ 0x18, /* ...##... */
+ /*044b:*/ 0x7e, /* .######. */
+ /*044c:*/ 0x18, /* ...##... */
+ /*044d:*/ 0x18, /* ...##... */
+ /*044e:*/ 0x18, /* ...##... */
+ /*044f:*/ 0x0e, /* ....###. */
+ /*0450:*/ 0x00, /* ........ */
+/* --- new character 'u' (117) starting at offset 0x0451 --- */
+ /*0451:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0456:*/ 0x00, /* ........ */
+ /*0457:*/ 0x00, /* ........ */
+ /*0458:*/ 0x66, /* .##..##. */
+ /*0459:*/ 0x66, /* .##..##. */
+ /*045a:*/ 0x66, /* .##..##. */
+ /*045b:*/ 0x66, /* .##..##. */
+ /*045c:*/ 0x3e, /* ..#####. */
+ /*045d:*/ 0x00, /* ........ */
+/* --- new character 'v' (118) starting at offset 0x045e --- */
+ /*045e:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0463:*/ 0x00, /* ........ */
+ /*0464:*/ 0x00, /* ........ */
+ /*0465:*/ 0x66, /* .##..##. */
+ /*0466:*/ 0x66, /* .##..##. */
+ /*0467:*/ 0x66, /* .##..##. */
+ /*0468:*/ 0x3c, /* ..####.. */
+ /*0469:*/ 0x18, /* ...##... */
+ /*046a:*/ 0x00, /* ........ */
+/* --- new character 'w' (119) starting at offset 0x046b --- */
+ /*046b:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0470:*/ 0x00, /* ........ */
+ /*0471:*/ 0x00, /* ........ */
+ /*0472:*/ 0x63, /* .##...## */
+ /*0473:*/ 0x6b, /* .##.#.## */
+ /*0474:*/ 0x7f, /* .####### */
+ /*0475:*/ 0x3e, /* ..#####. */
+ /*0476:*/ 0x36, /* ..##.##. */
+ /*0477:*/ 0x00, /* ........ */
+/* --- new character 'x' (120) starting at offset 0x0478 --- */
+ /*0478:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*047d:*/ 0x00, /* ........ */
+ /*047e:*/ 0x00, /* ........ */
+ /*047f:*/ 0x66, /* .##..##. */
+ /*0480:*/ 0x3c, /* ..####.. */
+ /*0481:*/ 0x18, /* ...##... */
+ /*0482:*/ 0x3c, /* ..####.. */
+ /*0483:*/ 0x66, /* .##..##. */
+ /*0484:*/ 0x00, /* ........ */
+/* --- new character 'y' (121) starting at offset 0x0485 --- */
+ /*0485:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*048a:*/ 0x00, /* ........ */
+ /*048b:*/ 0x00, /* ........ */
+ /*048c:*/ 0x66, /* .##..##. */
+ /*048d:*/ 0x66, /* .##..##. */
+ /*048e:*/ 0x66, /* .##..##. */
+ /*048f:*/ 0x3e, /* ..#####. */
+ /*0490:*/ 0x0c, /* ....##.. */
+ /*0491:*/ 0x78, /* .####... */
+/* --- new character 'z' (122) starting at offset 0x0492 --- */
+ /*0492:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0497:*/ 0x00, /* ........ */
+ /*0498:*/ 0x00, /* ........ */
+ /*0499:*/ 0x7e, /* .######. */
+ /*049a:*/ 0x0c, /* ....##.. */
+ /*049b:*/ 0x18, /* ...##... */
+ /*049c:*/ 0x30, /* ..##.... */
+ /*049d:*/ 0x7e, /* .######. */
+ /*049e:*/ 0x00, /* ........ */
+/* --- new character '{' (123) starting at offset 0x049f --- */
+ /*049f:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*04a4:*/ 0x1c, /* ...###.. */
+ /*04a5:*/ 0x30, /* ..##.... */
+ /*04a6:*/ 0x30, /* ..##.... */
+ /*04a7:*/ 0x60, /* .##..... */
+ /*04a8:*/ 0x30, /* ..##.... */
+ /*04a9:*/ 0x30, /* ..##.... */
+ /*04aa:*/ 0x1c, /* ...###.. */
+ /*04ab:*/ 0x00, /* ........ */
+/* --- new character '|' (124) starting at offset 0x04ac --- */
+ /*04ac:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*04b1:*/ 0x18, /* ...##... */
+ /*04b2:*/ 0x18, /* ...##... */
+ /*04b3:*/ 0x18, /* ...##... */
+ /*04b4:*/ 0x18, /* ...##... */
+ /*04b5:*/ 0x18, /* ...##... */
+ /*04b6:*/ 0x18, /* ...##... */
+ /*04b7:*/ 0x18, /* ...##... */
+ /*04b8:*/ 0x00, /* ........ */
+/* --- new character '}' (125) starting at offset 0x04b9 --- */
+ /*04b9:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*04be:*/ 0x38, /* ..###... */
+ /*04bf:*/ 0x0c, /* ....##.. */
+ /*04c0:*/ 0x0c, /* ....##.. */
+ /*04c1:*/ 0x06, /* .....##. */
+ /*04c2:*/ 0x0c, /* ....##.. */
+ /*04c3:*/ 0x0c, /* ....##.. */
+ /*04c4:*/ 0x38, /* ..###... */
+ /*04c5:*/ 0x00, /* ........ */
+/* --- new character '~' (126) starting at offset 0x04c6 --- */
+ /*04c6:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*04cb:*/ 0x33, /* ..##..## */
+ /*04cc:*/ 0x7e, /* .######. */
+ /*04cd:*/ 0xcc, /* ##..##.. */
+ /*04ce:*/ 0x00, /* ........ */
+ /*04cf:*/ 0x00, /* ........ */
+ /*04d0:*/ 0x00, /* ........ */
+ /*04d1:*/ 0x00, /* ........ */
+ /*04d2:*/ 0x00, /* ........ */
+/* --- new character '' (127) starting at offset 0x04d3 --- */
+ /*04d3:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*04d8:*/ 0x00, /* ........ */
+ /*04d9:*/ 0x08, /* ....#... */
+ /*04da:*/ 0x0c, /* ....##.. */
+ /*04db:*/ 0xfe, /* #######. */
+ /*04dc:*/ 0xfe, /* #######. */
+ /*04dd:*/ 0x0c, /* ....##.. */
+ /*04de:*/ 0x08, /* ....#... */
+ /*04df:*/ 0x00, /* ........ */
+};
+static const uint16_t font_c64_offsets[] = {
+ 0x0000 /* ' ' */,
+ 0x000d /* '!' */,
+ 0x001a /* '"' */,
+ 0x0027 /* '#' */,
+ 0x0034 /* '$' */,
+ 0x0041 /* '%' */,
+ 0x004e /* '&' */,
+ 0x005b /* ''' */,
+ 0x0068 /* '(' */,
+ 0x0075 /* ')' */,
+ 0x0082 /* '*' */,
+ 0x008f /* '+' */,
+ 0x009c /* ',' */,
+ 0x00a9 /* '-' */,
+ 0x00b6 /* '.' */,
+ 0x00c3 /* '/' */,
+ 0x00d0 /* '0' */,
+ 0x00dd /* '1' */,
+ 0x00ea /* '2' */,
+ 0x00f7 /* '3' */,
+ 0x0104 /* '4' */,
+ 0x0111 /* '5' */,
+ 0x011e /* '6' */,
+ 0x012b /* '7' */,
+ 0x0138 /* '8' */,
+ 0x0145 /* '9' */,
+ 0x0152 /* ':' */,
+ 0x015f /* ';' */,
+ 0x016c /* '<' */,
+ 0x0179 /* '=' */,
+ 0x0186 /* '>' */,
+ 0x0193 /* '?' */,
+ 0x01a0 /* '@' */,
+ 0x01ad /* 'A' */,
+ 0x01ba /* 'B' */,
+ 0x01c7 /* 'C' */,
+ 0x01d4 /* 'D' */,
+ 0x01e1 /* 'E' */,
+ 0x01ee /* 'F' */,
+ 0x01fb /* 'G' */,
+ 0x0208 /* 'H' */,
+ 0x0215 /* 'I' */,
+ 0x0222 /* 'J' */,
+ 0x022f /* 'K' */,
+ 0x023c /* 'L' */,
+ 0x0249 /* 'M' */,
+ 0x0256 /* 'N' */,
+ 0x0263 /* 'O' */,
+ 0x0270 /* 'P' */,
+ 0x027d /* 'Q' */,
+ 0x028a /* 'R' */,
+ 0x0297 /* 'S' */,
+ 0x02a4 /* 'T' */,
+ 0x02b1 /* 'U' */,
+ 0x02be /* 'V' */,
+ 0x02cb /* 'W' */,
+ 0x02d8 /* 'X' */,
+ 0x02e5 /* 'Y' */,
+ 0x02f2 /* 'Z' */,
+ 0x02ff /* '[' */,
+ 0x030c /* '\' */,
+ 0x0319 /* ']' */,
+ 0x0326 /* '^' */,
+ 0x0333 /* '_' */,
+ 0x0340 /* '`' */,
+ 0x034d /* 'a' */,
+ 0x035a /* 'b' */,
+ 0x0367 /* 'c' */,
+ 0x0374 /* 'd' */,
+ 0x0381 /* 'e' */,
+ 0x038e /* 'f' */,
+ 0x039b /* 'g' */,
+ 0x03a8 /* 'h' */,
+ 0x03b5 /* 'i' */,
+ 0x03c2 /* 'j' */,
+ 0x03cf /* 'k' */,
+ 0x03dc /* 'l' */,
+ 0x03e9 /* 'm' */,
+ 0x03f6 /* 'n' */,
+ 0x0403 /* 'o' */,
+ 0x0410 /* 'p' */,
+ 0x041d /* 'q' */,
+ 0x042a /* 'r' */,
+ 0x0437 /* 's' */,
+ 0x0444 /* 't' */,
+ 0x0451 /* 'u' */,
+ 0x045e /* 'v' */,
+ 0x046b /* 'w' */,
+ 0x0478 /* 'x' */,
+ 0x0485 /* 'y' */,
+ 0x0492 /* 'z' */,
+ 0x049f /* '{' */,
+ 0x04ac /* '|' */,
+ 0x04b9 /* '}' */,
+ 0x04c6 /* '~' */,
+ 0x04d3 /* '' */,
+};
+const struct fb_font font_c64 = {
+ .height = 8,
+ .ascent = 8,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_c64_data,
+ .charoffs = font_c64_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/fb_bw8.c b/Src/osmolib/src/target/firmware/fb/fb_bw8.c
new file mode 100644
index 0000000..ffb59d8
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_bw8.c
@@ -0,0 +1,311 @@
+/* utility functions for a black-and-white framebuffer organized
+ as 8-vertically-stacked-pixels per byte. This matches the
+ ST7558 LC Display Controller used on the Motorola C123 */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_bw8.h>
+
+#include <stdio.h> // debugging
+
+void fb_bw8_clear(){
+ int i,n;
+
+ /* bytes to clear */
+ n = (framebuffer->height+7)/8 * framebuffer->width;
+ for(i=0;i<n;i++)
+ fb_bw8->mem[i]=0;
+
+ /* mark everything as dirty */
+ fb_bw8->damage_x1 = 0;
+ fb_bw8->damage_x2 = framebuffer->width;
+ fb_bw8->damage_y1 = 0;
+ fb_bw8->damage_y2 = framebuffer->height;
+}
+
+/* update damage rectangle to include the area
+ x1,y1 (upper left) to x2,y2 (lower right)
+ Note that all pixels *including* x1y2 and x2y2 are
+ marked as dirty */
+static void fb_bw8_update_damage(
+ uint16_t x1,uint16_t y1, /* left upper corner (inclusive) */
+ uint16_t x2,uint16_t y2 /* right lower corner (inclusive) */
+){
+ fb_sanitize_box(&x1,&y1,&x2,&y2);
+
+ x2++; /* see definition of fb_bw8->damage_x2/y2 */
+ y2++;
+
+ /* maybe currently everything is clean? */
+ if(fb_bw8->damage_x1 == fb_bw8->damage_x2 ||
+ fb_bw8->damage_y1 == fb_bw8->damage_y2){
+ fb_bw8->damage_x1 = x1;
+ fb_bw8->damage_y1 = y1;
+ fb_bw8->damage_x2 = x2;
+ fb_bw8->damage_y2 = y2;
+/*
+ printf("%s: was clean! damage now %d %d %d %d\n",
+ __FUNCTION__,fb_bw8->damage_x1,fb_bw8->damage_y1,
+ fb_bw8->damage_x2,fb_bw8->damage_y2);
+*/
+ return;
+ }
+
+ /* grow damage box */
+ if(x1 < fb_bw8->damage_x1)
+ fb_bw8->damage_x1 = x1;
+ if(y1 < fb_bw8->damage_y1)
+ fb_bw8->damage_y1 = y1;
+ if(x2 > fb_bw8->damage_x2)
+ fb_bw8->damage_x2 = x2;
+ if(y2 > fb_bw8->damage_y2)
+ fb_bw8->damage_y2 = y2;
+#if 0
+ printf("%s: damage now %d %d %d %d\n",
+ __FUNCTION__,fb_bw8->damage_x1,fb_bw8->damage_y1,
+ fb_bw8->damage_x2,fb_bw8->damage_y2);
+#endif
+}
+
+static void fb_bw8_line(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2){
+ fb_sanitize_box(&x1,&y1,&x2,&y2);
+ /* FIXME : this is currently unimplemented! */
+}
+
+void fb_bw8_lineto(uint16_t x,uint16_t y){
+ fb_bw8_line(framebuffer->cursor_x,framebuffer->cursor_y,x,y);
+ framebuffer->cursor_x = x;
+ framebuffer->cursor_y = y;
+}
+
+/* depending on color set (add to or_mask) or clear
+ (remove from and_mask) bit number bitnum */
+static void set_pixel(uint8_t *and_mask,
+ uint8_t *or_mask,
+ int bitnum,
+ uint32_t color
+){
+ if(color == FB_COLOR_TRANSP)
+ return;
+ if(color == FB_COLOR_WHITE)
+ *and_mask &= ~(1<<bitnum);
+ else
+ *or_mask |= 1<<bitnum;
+}
+
+static void set_fg_pixel(uint8_t *and_mask,uint8_t *or_mask,int bitnum){
+ set_pixel(and_mask,or_mask,bitnum,framebuffer->fg_color);
+}
+
+static void set_bg_pixel(uint8_t *and_mask,uint8_t *or_mask,int bitnum){
+ set_pixel(and_mask,or_mask,bitnum,framebuffer->bg_color);
+}
+
+static void fb_bw8_box(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
+{
+ uint16_t y,w;
+ uint8_t *p;
+
+ uint8_t and_mask,or_mask; // filling
+ uint8_t and_mask_side,or_mask_side; // left and right side
+
+ fb_sanitize_box(&x1,&y1,&x2,&y2);
+ fb_bw8_update_damage(x1,y1,x2,y2);
+
+ for(y=y1&0xfff8;y<=y2;y+=8){
+ /* don't clear any pixels (white) */
+ and_mask = and_mask_side = 0xff;
+ or_mask = or_mask_side = 0;
+
+ for(w=0;w<8;w++){ /* check which pixels are affected */
+ if(y+w >= y1 && y+w <= y2){
+ set_bg_pixel(&and_mask,&or_mask,w);
+ set_fg_pixel(&and_mask_side,&or_mask_side,w);
+ }
+
+ if(y+w == y1 || y+w == y2){ /* top and bottom line */
+ set_fg_pixel(&and_mask,&or_mask,w);
+ }
+ }
+
+ p = fb_bw8->mem + (y/8)*framebuffer->width + x1;
+ for(w=x1;w<=x2;w++){
+ if(w == x1 || w == x2)
+ *p = (*p & and_mask_side)|or_mask_side;
+ else
+ *p = (*p & and_mask)|or_mask;
+ p++;
+ }
+ }
+}
+
+/* draw box from cursor to (x,y) */
+void
+fb_bw8_boxto(uint16_t x,uint16_t y){
+ fb_bw8_box(framebuffer->cursor_x,framebuffer->cursor_y,x,y);
+ framebuffer->cursor_x = x;
+ framebuffer->cursor_y = y;
+}
+
+/* this is the most ridiculous function ever, because it has to
+ fiddle with two braindead bitmaps at once, both being
+ organized differently */
+
+/* draw text at current position, with current font and colours up
+ to a width of maxwidth pixels, return pixelwidth consumed */
+
+int
+fb_bw8_putstr(char *str,int maxwidth){
+ const struct fb_font *font = fb_fonts[framebuffer->font];
+ const struct fb_char *fchr;
+
+ int x1,y1,x2,y2; // will become bounding box
+ int w; // 0..7 while building bits per byte
+ int y; // coordinates in display
+ int char_x,char_y; // coordinates in font character
+ int bitmap_x,bitmap_y; // coordinates in character's bitmap
+ int byte_per_line; // depending on character width in font
+ int bitmap_offs,bitmap_bit; // offset inside bitmap, bit number of pixel
+ int fb8_offs; // offset to current pixel in framebuffer
+ uint8_t and_mask,or_mask; // to draw on framebuffer
+ uint8_t *p; // pointer into framebuffer memorya
+ int total_w; // total width
+
+ /* center, if maxwidth < 0 */
+ if (maxwidth < 0) {
+ total_w = 0;
+ /* count width of string */
+ for(p=(uint8_t *)str;*p;p++){
+ fchr = fb_font_get_char(font,*p);
+ if(!fchr) /* FIXME: Does '?' exist in every font? */
+ fchr = fb_font_get_char(font,'?');
+ total_w += fchr->width;
+
+ } // str
+ if (total_w <= framebuffer->width)
+ framebuffer->cursor_x =
+ (framebuffer->width - total_w) >> 1;
+ maxwidth = framebuffer->width;
+ }
+
+ x1 = framebuffer->cursor_x; // first col (incl!)
+ x2 = x1 + maxwidth - 1; // last col (incl!)
+ if(x2 >= framebuffer->width)
+ x2 = framebuffer->width - 1;
+
+ y1 = framebuffer->cursor_y - font->ascent + 1; // first row
+ y2 = y1 + font->height - 1; // last row
+
+#if 0
+ printf("%s: %d %d %d %d\n",__FUNCTION__,x1,y1,x2,y2);
+#endif
+
+ if(y1 < 0) // sanitize in case of overflow
+ y1 = 0;
+ if(y2 >= framebuffer->height)
+ y2 = framebuffer->height - 1;
+
+ fb8_offs = x1 + (y1 & 0xfff8)/8;
+
+ /* iterate over all characters */
+ for(;*str && framebuffer->cursor_x <= x2;str++){
+ fchr = fb_font_get_char(font,*str);
+ if(!fchr) /* FIXME: Does '?' exist in every font? */
+ fchr = fb_font_get_char(font,'?');
+
+ byte_per_line = (fchr->bbox_w+7)/8;;
+
+ /* character pixels, left to right */
+ for(char_x=0;
+ char_x<fchr->width && char_x + framebuffer->cursor_x <= x2;
+ char_x++
+ ){
+ /* character pixels, top to bottom, in stripes
+ of 8 to match LCD RAM organisation */
+ for(y=y1&0xfff8;y<=y2;y+=8){ // display lines
+ /* bitmap coordinates, X= left to right */
+ bitmap_x = char_x - fchr->bbox_x;
+ /* character coords. Y increases from
+ cursor upwards */
+ char_y = framebuffer->cursor_y-y;
+ /* bitmap index = height-(bitmap coords)-1 */
+ bitmap_y = fchr->bbox_h -
+ (char_y - fchr->bbox_y) - 1;
+
+ fb8_offs = framebuffer->cursor_x +
+ char_x + (y/8)*framebuffer->width;
+
+ and_mask = 0xff;
+ or_mask = 0x00;
+
+ /* top to bottom inside of a 8bit column */
+ for(w=0;w<8;w++,bitmap_y++){
+ /* inside drawing area? */
+ if(y+w < y1 || y+w > y2)
+ continue;
+
+ /* outside pixel data of this
+ character? */
+ if(bitmap_x < 0 ||
+ bitmap_x >= fchr->bbox_w ||
+ bitmap_y < 0 ||
+ bitmap_y >= fchr->bbox_h
+ )
+ goto outside_char_bitmap;
+
+ /* check bit in pixel data for
+ this character */
+ bitmap_offs = bitmap_x/8+
+ bitmap_y*byte_per_line;
+ bitmap_bit = 7-(bitmap_x%8);
+
+ /* bit is set */
+ if(fchr->data[bitmap_offs] &
+ (1<<bitmap_bit)){
+ set_fg_pixel(&and_mask,
+ &or_mask,w);
+ } else { // unset, or outside bitmap
+outside_char_bitmap:
+ set_bg_pixel(&and_mask,
+ &or_mask,w);
+ }
+ } // for(w...)
+ /* adjust byte in framebuffer */
+ p = fb_bw8->mem + fb8_offs;
+ *p = ( *p & and_mask ) | or_mask;
+ } // for(y...)
+ } // for(char_x...)
+ framebuffer->cursor_x += char_x;
+ } // str
+
+ x2 = framebuffer->cursor_x;
+ fb_bw8_update_damage(x1,y1,x2,y2);
+ return x2-x1;
+}
+
+int
+fb_bw8_putchar(char c,int maxwidth){
+ char tmp[2];
+ tmp[0]=c;
+ tmp[1]=c;
+ return fb_bw8_putstr(tmp,maxwidth);
+}
diff --git a/Src/osmolib/src/target/firmware/fb/fb_dummy.c b/Src/osmolib/src/target/firmware/fb/fb_dummy.c
new file mode 100644
index 0000000..cb053de
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_dummy.c
@@ -0,0 +1,70 @@
+/*
+ "hardware" driver for a dummy framebuffer. Used when no
+ display hardware is supported
+ */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <defines.h>
+
+static void
+fb_dummy_init(){
+}
+
+static void
+fb_dummy_clear(){
+}
+
+static void
+fb_dummy_boxto(uint16_t x,uint16_t y){
+ framebuffer->cursor_x = x;
+ framebuffer->cursor_y = y;
+}
+
+static void
+fb_dummy_lineto(uint16_t x,uint16_t y){
+ framebuffer->cursor_x = x;
+ framebuffer->cursor_y = y;
+}
+
+static int
+fb_dummy_putstr(__unused char *c, __unused int maxwidth){
+ return 0;
+}
+
+static void
+fb_dummy_flush(){
+}
+
+struct framebuffer fb_dummy_framebuffer = {
+ .name = "dummyfb",
+ .init = fb_dummy_init,
+ .clear = fb_dummy_clear,
+ .boxto = fb_dummy_boxto,
+ .lineto = fb_dummy_lineto,
+ .putstr = fb_dummy_putstr,
+ .flush = fb_dummy_flush,
+ .width = 128,
+ .height = 64
+};
+
+struct framebuffer *framebuffer = & fb_dummy_framebuffer;
diff --git a/Src/osmolib/src/target/firmware/fb/fb_rgb332.c b/Src/osmolib/src/target/firmware/fb/fb_rgb332.c
new file mode 100644
index 0000000..08d64e1
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_rgb332.c
@@ -0,0 +1,305 @@
+/* utility functions for a color framebuffer organized
+ as one pixel per byte, with bits mapped as RRRGGGBB.
+ This matches the SSD1783 LC Display Controller used
+ on the Motorola C155 */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_rgb332.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+fb_rgb332_clear(){
+ int i,n;
+
+ /* bytes to clear */
+ n = framebuffer->height * framebuffer->width;
+ for(i=0;i<n;i++)
+ fb_rgb332->mem[i]=0xff; /* white */
+
+ /* mark everything as dirty */
+ fb_rgb332->damage_x1 = 0;
+ fb_rgb332->damage_x2 = framebuffer->width;
+ fb_rgb332->damage_y1 = 0;
+ fb_rgb332->damage_y2 = framebuffer->height;
+}
+
+/* update damage rectangle to include the area
+ x1,y1 (upper left) to x2,y2 (lower right)
+ Note that all pixels *including* x1y2 and x2y2 are
+ marked as dirty */
+static void
+fb_rgb332_update_damage(
+ uint16_t x1,uint16_t y1, /* left upper corner (inclusive) */
+ uint16_t x2,uint16_t y2 /* right lower corner (inclusive) */
+){
+ fb_sanitize_box(&x1,&y1,&x2,&y2);
+
+ x2++; /* see definition of fb_rgb332->damage_x2/y2 */
+ y2++;
+
+ /* maybe currently everything is clean? */
+ if(fb_rgb332->damage_x1 == fb_rgb332->damage_x2 ||
+ fb_rgb332->damage_y1 == fb_rgb332->damage_y2
+ ){
+ fb_rgb332->damage_x1 = x1;
+ fb_rgb332->damage_y1 = y1;
+ fb_rgb332->damage_x2 = x2;
+ fb_rgb332->damage_y2 = y2;
+ return;
+ }
+
+ /* grow damage box */
+ if(x1 < fb_rgb332->damage_x1)
+ fb_rgb332->damage_x1 = x1;
+ if(y1 < fb_rgb332->damage_y1)
+ fb_rgb332->damage_y1 = y1;
+ if(x2 > fb_rgb332->damage_x2)
+ fb_rgb332->damage_x2 = x2;
+ if(y2 > fb_rgb332->damage_y2)
+ fb_rgb332->damage_y2 = y2;
+#if 0
+ printf("%s: damage now %d %d %d %d\n",
+ __FUNCTION__,fb_rgb332->damage_x1,fb_rgb332->damage_y1,
+ fb_rgb332->damage_x2,fb_rgb332->damage_y2);
+#endif
+}
+
+/* we trust gcc to move this expensive bitshifting out of
+ the loops in the drawing funtcions */
+static uint8_t rgb_to_pixel(uint32_t color){
+ uint8_t ret;
+ ret = (FB_COLOR_TO_R(color) & 0xe0); /* 765 = RRR */
+ ret |= (FB_COLOR_TO_G(color) & 0xe0) >> 3; /* 432 = GGG */
+ ret |= (FB_COLOR_TO_B(color) & 0xc0) >> 6; /* 10 = BB */
+ return ret;
+}
+
+static void set_pix(uint8_t *pixel,uint32_t color){
+ if(color == FB_COLOR_TRANSP)
+ return;
+ *pixel = rgb_to_pixel(color);
+}
+
+static void set_fg(uint8_t *pixel){
+ set_pix(pixel,framebuffer->fg_color);
+}
+
+static void set_bg(uint8_t *pixel){
+ set_pix(pixel,framebuffer->bg_color);
+}
+
+void fb_rgb332_boxto(uint16_t x2,uint16_t y2)
+{
+ uint16_t x1 = framebuffer->cursor_x;
+ uint16_t y1 = framebuffer->cursor_y;
+ int x,y;
+ uint8_t *p;
+
+ framebuffer->cursor_x = x2;
+ framebuffer->cursor_y = y2;
+
+ fb_sanitize_box(&x1,&y1,&x2,&y2);
+ fb_rgb332_update_damage(x1,y1,x2,y2);
+
+ for(y=y1; y<=y2; y++){
+ p = & fb_rgb332->mem[x1 + framebuffer->width * y];
+ for(x=x1;x<=x2;x++){
+ set_bg(p);
+ if(y==y1 || y==y2 || x==x1 || x==x2) /* border */
+ set_fg(p);
+ p++;
+ }
+ }
+}
+
+/* draw a line like Brensenham did... (roughly) */
+void fb_rgb332_lineto(uint16_t x2,uint16_t y2){
+ uint8_t *p,pixel; /* framebuffer pointer */
+ int delta_regular; /* framebuffer offset per step */
+ int delta_step; /* " */
+
+ uint16_t x1 = framebuffer->cursor_x; /* start */
+ uint16_t y1 = framebuffer->cursor_y;
+
+ int t,tmax; /* counter for steps */
+ int err_inc,err_accu=0; /* error delta and accumulator for */
+ /* Brensenham's algorhithm */
+
+ fb_limit_fb_range(&x1,&y1);
+ fb_limit_fb_range(&x2,&y2);
+ fb_rgb332_update_damage(x1,y1,x2,y2);
+
+ framebuffer->cursor_x = x2; /* end pixel */
+ framebuffer->cursor_y = y2;
+
+ /* pointer to first pixel, pixel value in FB memory */
+ p = fb_rgb332->mem + framebuffer->width * y1 + x1;
+ pixel = rgb_to_pixel(framebuffer->fg_color);
+
+ if(abs(x2-x1) >= abs(y2-y1)){ /* shallow line */
+ /* set pointer deltas for directions */
+ delta_regular = 1; /* X */
+ if(x2 < x1)
+ delta_regular = -delta_regular;
+ delta_step = framebuffer->width; /* Y */
+ if(y2 < y1)
+ delta_step = -delta_step;
+ tmax = abs(x2-x1);
+ err_inc = abs(y2-y1);
+ } else { /* steep line */
+ delta_regular = framebuffer->width; /* Y */
+ if(y2 < y1)
+ delta_regular = -delta_regular;
+ delta_step = 1; /* X */
+ if(x2 < x1)
+ delta_step = -1;
+ tmax = abs(y2-y1);
+ err_inc = abs(x2-y1);
+ }
+
+#if 0
+ printf("%s: (%d,%d) -> (%d,%d) step=%d regular=%d err_inc=%d tmax=%d\n",
+ __FUNCTION__,x1,y1,x2,y2,delta_step,delta_regular,err_inc,tmax);
+#endif
+
+ for(t=0;t<=tmax;t++){
+ *p = pixel;
+ err_accu += err_inc;
+ if(err_accu >= tmax){
+ p += delta_step;
+ err_accu -= tmax;
+ }
+ p += delta_regular;
+ }
+}
+
+int fb_rgb332_putstr(char *str,int maxwidth){
+ const struct fb_font *font = fb_fonts[framebuffer->font];
+ const struct fb_char *fchr;
+
+ int x1,y1,x2,y2; // will become bounding box
+ int y; // coordinates in display
+ int char_x=0,char_y; // coordinates in font character
+ int bitmap_x,bitmap_y; // coordinates in character's bitmap
+ int byte_per_line; // depending on character width in font
+ int bitmap_offs,bitmap_bit; // offset inside bitmap, bit number of pixel
+ uint8_t *p,fgpixel,bgpixel,trans; // pointer into framebuffer memory
+ int total_w; // total width
+
+ /* center, if maxwidth < 0 */
+ if (maxwidth < 0) {
+ total_w = 0;
+ /* count width of string */
+ for(p=(uint8_t *)str;*p;p++){
+ fchr = fb_font_get_char(font,*p);
+ if(!fchr) /* FIXME: Does '?' exist in every font? */
+ fchr = fb_font_get_char(font,'?');
+ total_w += fchr->width;
+
+ } // str
+ if (total_w <= framebuffer->width)
+ framebuffer->cursor_x =
+ (framebuffer->width - total_w) >> 1;
+ else
+ framebuffer->cursor_x = 1;
+ maxwidth = framebuffer->width;
+ }
+
+ x1 = framebuffer->cursor_x; // first col (incl!)
+ x2 = x1 + maxwidth - 1; // last col (incl!)
+ if(x2 >= framebuffer->width)
+ x2 = framebuffer->width - 1;
+
+ y1 = framebuffer->cursor_y - font->ascent + 1; // first row
+ y2 = y1 + font->height - 1; // last row
+
+ fgpixel = rgb_to_pixel(framebuffer->fg_color);
+ bgpixel = rgb_to_pixel(framebuffer->bg_color);
+ trans = (framebuffer->bg_color == FB_COLOR_TRANSP);
+
+ if(y1 < 0) // sanitize in case of overflow
+ y1 = 0;
+ if(y2 >= framebuffer->height)
+ y2 = framebuffer->height - 1;
+
+ /* iterate over all characters */
+ for(;*str && framebuffer->cursor_x <= x2;str++){
+ fchr = fb_font_get_char(font,*str);
+ if(!fchr) /* FIXME: Does '?' exist in every font? */
+ fchr = fb_font_get_char(font,'?');
+ if(!fchr)
+ return 0;
+ byte_per_line = (fchr->bbox_w+7)/8;
+
+ for(y=y1;y<=y2;y++){
+ p=fb_rgb332->mem+y*framebuffer->width;
+ p+=framebuffer->cursor_x;
+
+ for(char_x=0;
+ char_x<fchr->width &&
+ char_x+framebuffer->cursor_x <= x2;
+ char_x++
+ ){
+ /* bitmap coordinates, X= left to right */
+ bitmap_x = char_x - fchr->bbox_x;
+ /* character coords. Y increases from
+ cursor upwards */
+ char_y = framebuffer->cursor_y-y;
+ /* bitmap index = height-(bitmap coords)-1 */
+ bitmap_y = fchr->bbox_h -
+ (char_y - fchr->bbox_y) - 1;
+
+ /* outside pixel data of this
+ character? */
+ if(bitmap_x < 0 ||
+ bitmap_x >= fchr->bbox_w ||
+ bitmap_y < 0 ||
+ bitmap_y >= fchr->bbox_h
+ )
+ goto outside_char_bitmap;
+
+ /* check bit in pixel data for
+ this character */
+ bitmap_offs=bitmap_x/8+bitmap_y*byte_per_line;
+ bitmap_bit=7-(bitmap_x%8);
+
+ /* bit is set */
+ if(fchr->data[bitmap_offs]&(1<<bitmap_bit)){
+ *p = fgpixel;
+ } else { // unset, or outside bitmap
+outside_char_bitmap:
+ if (!trans)
+ *p = bgpixel;
+ }
+ p++;
+ } // for(x...)
+ } // for(char_x...)
+ framebuffer->cursor_x += char_x;
+ } // str
+
+ x2 = framebuffer->cursor_x;
+ fb_rgb332_update_damage(x1,y1,x2,y2);
+ return x2-x1;
+}
+
diff --git a/Src/osmolib/src/target/firmware/fb/fb_s6b33b1x.c b/Src/osmolib/src/target/firmware/fb/fb_s6b33b1x.c
new file mode 100644
index 0000000..3629a10
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_s6b33b1x.c
@@ -0,0 +1,193 @@
+/* Framebuffer implementation - combined Sunplus SPCA552E and
+ * Samsung S6B33B1X LCD driver - as used in the Pirelli DP-L10 */
+
+/* (C) 2012 by Steve Markgraf <steve@steve-m.de>
+ *
+ * based on fb_ssd1783.c:
+ * (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_rgb332.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <delay.h>
+#include <memory.h>
+
+#define S6B33B1X_WIDTH 128
+#define S6B33B1X_HEIGHT 128
+#define LCD_INVIS_X_PIXELS 4
+
+#define ARMIO_LATCH_OUT 0xfffe4802
+#define nCS4_ADDR 0x02800000
+
+static uint8_t fb_s6b33b1x_mem[S6B33B1X_WIDTH * S6B33B1X_HEIGHT];
+
+enum s6b33b1x_cmdflag { CMD, DATA, END };
+
+struct s6b33b1x_cmdlist {
+ enum s6b33b1x_cmdflag is_cmd:8; /* 1: is a command, 0: is data, 2: end marker! */
+ uint8_t data; /* 8 bit to send to LC display */
+} __attribute__((packed));
+
+static const struct s6b33b1x_cmdlist
+s6b33b1x_initdata[] = {
+ { CMD, 0x26 }, /* CMD DCDC and AMP ON/OFF set */
+ { DATA, 0x00 }, /* DATA: everything off */
+ { CMD, 0x02 }, /* CMD Oscillation Mode Set */
+ { DATA, 0x00 }, /* DATA: oscillator off */
+ { CMD, 0x2c }, /* CMD Standby Mode off */
+ { CMD, 0x50 }, /* CMD Display off */
+ { CMD, 0x02 }, /* CMD Oscillation Mode Set */
+ { DATA, 0x01 }, /* DATA: oscillator on */
+ { CMD, 0x26 }, /* CMD DCDC and AMP ON/OFF set */
+ { DATA, 0x01 }, /* DATA: Booster 1 on */
+ { CMD, 0x26 }, /* CMD DCDC and AMP ON/OFF set */
+ { DATA, 0x09 }, /* DATA: Booster 1 on, OP-AMP on */
+ { CMD, 0x26 }, /* CMD DCDC and AMP ON/OFF set */
+ { DATA, 0x0b }, /* DATA: Booster 1 + 2 on, OP-AMP on */
+ { CMD, 0x26 }, /* CMD DCDC and AMP ON/OFF set */
+ { DATA, 0x0f }, /* DATA: Booster 1 + 2 + 3 on, OP-AMP on */
+ { CMD, 0x20 }, /* CMD DC-DC Select */
+ { DATA, 0x01 }, /* DATA: step up x1.5 */
+ { CMD, 0x24 }, /* CMD DCDC Clock Division Set */
+ { DATA, 0x0a }, /* DATA: fPCK = fOSC/6 */
+ { CMD, 0x2a }, /* CMD Contrast Control */
+ { DATA, 0x2d }, /* DATA: default contrast */
+ { CMD, 0x30 }, /* CMD Adressing mode set */
+ { DATA, 0x0b }, /* DATA: 65536 color mode */
+ { CMD, 0x10 }, /* CMD Driver output mode set */
+ { DATA, 0x03 }, /* DATA: Display duty: 1/132 */
+ { CMD, 0x34 }, /* CMD N-line inversion set */
+ { DATA, 0x88 }, /* DATA: inversion on, one frame, every 8 blocks */
+ { CMD, 0x40 }, /* CMD Entry mode set */
+ { DATA, 0x00 }, /* DATA: Y address counter mode */
+ { CMD, 0x28 }, /* CMD Temperature Compensation set */
+ { DATA, 0x01 }, /* DATA: slope -0.05%/degC */
+ { CMD, 0x32 }, /* CMD ROW vector mode set */
+ { DATA, 0x01 }, /* DATA: every 2 subgroup */
+ { CMD, 0x51 }, /* CMD Display on */
+ { END, 0x00 }, /* MARKER: end of list */
+};
+
+static void fb_s6b33b1x_send_cmdlist(const struct s6b33b1x_cmdlist *p)
+{
+ while(p->is_cmd != END){
+ writew(p->data, nCS4_ADDR);
+ p++;
+ }
+}
+
+static void fb_spca_write(uint16_t addr, uint16_t val)
+{
+ writew(addr, nCS4_ADDR);
+ writew(val , nCS4_ADDR | 2);
+}
+
+static void fb_spca_init(void)
+{
+ uint16_t reg;
+
+ /* Initialize Sunplus SPCA552E Media Controller for bypass mode */
+ fb_spca_write(0x7e, 0x00); /* internal register access */
+ delay_ms(10);
+ fb_spca_write(0x7a, 0x00); /* keep CPU in reset state */
+ delay_ms(10);
+ fb_spca_write(0x7f, 0x00); /* select main page */
+ delay_ms(5);
+ fb_spca_write(0x72, 0x07); /* don't reshape timing, 16 bit mode */
+ fb_spca_write(0x14, 0x03);
+ fb_spca_write(0x7f, 0x00); /* select main page */
+ delay_ms(5);
+ fb_spca_write(0x06, 0xff);
+ fb_spca_write(0x7f, 0x09);
+ fb_spca_write(0x19, 0x08); /* backlight: 0x08 is on, 0x0c is off */
+ fb_spca_write(0x23, 0x18);
+
+ /* enable bypass mode */
+ reg = readw(ARMIO_LATCH_OUT);
+ reg |= (1 << 7);
+ writew(reg, ARMIO_LATCH_OUT);
+}
+
+static void fb_s6b33b1x_init(void)
+{
+ printf("%s: initializing LCD.\n",__FUNCTION__);
+
+ fb_spca_init();
+ fb_s6b33b1x_send_cmdlist(s6b33b1x_initdata);
+}
+
+static void fb_s6b33b1x_flush(void)
+{
+ int x,y;
+ uint8_t *p;
+ struct s6b33b1x_cmdlist prepare_disp_write_cmds[] = {
+ { CMD, 0x42 }, /* set column address */
+ { DATA, fb_rgb332->damage_x1 + LCD_INVIS_X_PIXELS },
+ { DATA, fb_rgb332->damage_x2 + LCD_INVIS_X_PIXELS - 1 },
+ { CMD, 0x43 }, /* set page address (Y) */
+ { DATA, fb_rgb332->damage_y1 },
+ { DATA, fb_rgb332->damage_y2 - 1 },
+ { END, 0x00 }
+ };
+
+ /* If everything's clean, just return */
+ if(fb_rgb332->damage_x1 == fb_rgb332->damage_x2 ||
+ fb_rgb332->damage_y1 == fb_rgb332->damage_y2) {
+ printf("%s: no damage\n",__FUNCTION__);
+ return;
+ }
+
+ fb_s6b33b1x_send_cmdlist(prepare_disp_write_cmds);
+
+ for(y=fb_rgb332->damage_y1;y<fb_rgb332->damage_y2;y++) {
+ p = & fb_rgb332->mem[y * framebuffer->width]; // start of line
+ p += fb_rgb332->damage_x1; // start of damage area
+
+ for(x=fb_rgb332->damage_x1; x<fb_rgb332->damage_x2; x++) {
+ uint16_t data = rgb332_to_565(*p++);
+ writew(data , nCS4_ADDR | 2);
+ }
+ }
+
+ fb_rgb332->damage_x1 = fb_rgb332->damage_x2 = 0;
+ fb_rgb332->damage_y1 = fb_rgb332->damage_y2 = 0;
+}
+
+static struct framebuffer fb_s6b33b1x_framebuffer = {
+ .name = "s6b33b1x",
+ .init = fb_s6b33b1x_init,
+ .clear = fb_rgb332_clear,
+ .boxto = fb_rgb332_boxto,
+ .lineto = fb_rgb332_lineto,
+ .putstr = fb_rgb332_putstr,
+ .flush = fb_s6b33b1x_flush,
+ .width = S6B33B1X_WIDTH,
+ .height = S6B33B1X_HEIGHT
+};
+
+static struct fb_rgb332 fb_s6b33b1x_rgb332 = {
+ .mem = fb_s6b33b1x_mem
+};
+
+struct framebuffer *framebuffer = &fb_s6b33b1x_framebuffer;
+struct fb_rgb332 *fb_rgb332 = &fb_s6b33b1x_rgb332;
diff --git a/Src/osmolib/src/target/firmware/fb/fb_ssd1783.c b/Src/osmolib/src/target/firmware/fb/fb_ssd1783.c
new file mode 100644
index 0000000..cacdce0
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_ssd1783.c
@@ -0,0 +1,204 @@
+/* Framebuffer implementation - SSD1783 LCD driver for C155 */
+/* Based on ssd1783.c by Steve Markgraf and Harald Welte */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_rgb332.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <delay.h>
+#include <uwire.h>
+#include <calypso/clock.h>
+
+#define SSD1783_WIDTH 98
+#define SSD1783_HEIGHT 67
+#define SSD1783_UWIRE_BITLEN 9
+#define SSD1783_DEV_ID 0
+
+#define LCD_TOP_FREE_ROWS 3
+#define LCD_LEFT_FREE_COLS 0
+#define PIXEL_BYTES 3
+#define FONT_HEIGHT 8
+#define FONT_WIDTH 8
+
+static uint8_t fb_ssd1783_mem[SSD1783_WIDTH * SSD1783_HEIGHT];
+
+enum ssd1783_cmdflag { CMD, DATA, END };
+
+struct ssd1783_cmdlist {
+ enum ssd1783_cmdflag is_cmd:8; /* 1: is a command, 0: is data, 2: end marker! */
+ uint8_t data; /* 8 bit to send to LC display */
+} __attribute__((packed));
+
+static const struct ssd1783_cmdlist
+ssd1783_initdata[] = {
+ { CMD, 0xD1 }, /* CMD set internal oscillator on */
+ { CMD, 0x94 }, /* CMD leave sleep mode */
+ { CMD, 0xbb }, /* CMD Set COM Output Scan Direction: */
+ { DATA, 0x01 }, /* DATA: 01: COM0-79, then COM159-80 */
+/* -------- DIFFERENT FROM ORIGINAL CODE: -------------- */
+/* we use 8bit per pixel packed RGB 332 */
+ { CMD, 0xbc }, /* CMD Set Data Output Scan Direction */
+ { DATA, 0x00 }, /* DATA: column scan, normal rotation, normal display */
+ { DATA, 0x00 }, /* DATA: RGB color arrangement R G B R G B ... */
+/*-->*/ { DATA, 0x01 }, /* DATA: 8 bit per pixel mode MSB <RRRGGGBB> LSB */
+/* --------- /DIFFERENT ---------- */
+ { CMD, 0xce }, /* CMD Set 256 Color Look Up Table LUT */
+ { DATA, 0x00 }, /* DATA red 000 */
+ { DATA, 0x03 }, /* DATA red 001 */
+ { DATA, 0x05 }, /* DATA red 010 */
+ { DATA, 0x07 }, /* DATA red 011 */
+ { DATA, 0x09 }, /* DATA red 100 */
+ { DATA, 0x0b }, /* DATA red 101 */
+ { DATA, 0x0d }, /* DATA red 110 */
+ { DATA, 0x0f }, /* DATA red 111 */
+ { DATA, 0x00 }, /* DATA green 000 */
+ { DATA, 0x03 }, /* DATA green 001 */
+ { DATA, 0x05 }, /* DATA green 010 */
+ { DATA, 0x07 }, /* DATA green 011 */
+ { DATA, 0x09 }, /* DATA green 100 */
+ { DATA, 0x0b }, /* DATA green 101 */
+ { DATA, 0x0d }, /* DATA green 110 */
+ { DATA, 0x0f }, /* DATA green 111 */
+ { DATA, 0x00 }, /* DATA blue 00 */
+ { DATA, 0x05 }, /* DATA blue 01 */
+ { DATA, 0x0a }, /* DATA blue 10 */
+ { DATA, 0x0f }, /* DATA blue 11 */
+ { CMD, 0xca }, /* CMD Set Display Control - Driver Duty Selection */
+ { DATA, 0xff }, // can't find description of the values in the original
+ { DATA, 0x10 }, // display/ssd1783.c in my datasheet :-(
+ { DATA, 0x01 }, //
+ { CMD, 0xab }, /* CMD Set Scroll Start */
+ { DATA, 0x00 }, /* DATA: Starting address at block 0 */
+ { CMD, 0x20 }, /* CMD Set power control register */
+ { DATA, 0x0b }, /* DATA: booster 6x, reference gen. & int regulator */
+ { CMD, 0x81 }, /* CMD Contrast Lvl & Int. Regul. Resistor Ratio */
+ { DATA, 0x29 }, /* DATA: contrast = 0x29 */
+ { DATA, 0x05 }, /* DATA: 0x05 = 0b101 -> 1+R2/R1 = 11.37 */
+ { CMD, 0xa7 }, /* CMD Invert Display */
+ { CMD, 0x82 }, /* CMD Set Temperature Compensation Coefficient */
+ { DATA, 0x00 }, /* DATA: Gradient is -0.10 % / degC */
+ { CMD, 0xfb }, /* CMD Set Biasing Ratio */
+ { DATA, 0x03 }, /* DATA: 1/10 bias */
+ { CMD, 0xf2 }, /* CMD Set Frame Frequency and N-line inversion */
+ { DATA, 0x08 }, /* DATA: 75 Hz (POR) */
+ { DATA, 0x06 }, /* DATA: n-line inversion: 6 lines */
+ { CMD, 0xf7 }, /* CMD Select PWM/FRC Select Full Col./8col mode */
+ { DATA, 0x28 }, /* DATA: always 0x28 */
+ { DATA, 0x8c }, /* DATA: 4bit PWM + 2 bit FRC */
+ { DATA, 0x05 }, /* DATA: full color mode */
+ { CMD, 0xaf }, /* CMD Display On */
+ { END, 0x00 }, /* MARKER: end of list */
+};
+
+static void
+fb_ssd1783_send_cmdlist(const struct ssd1783_cmdlist *p){
+ int i=0;
+ while(p->is_cmd != END){
+ uint16_t sendcmd = p->data;
+ if(p->is_cmd == DATA)
+ sendcmd |= 0x0100; /* 9th bit is cmd/data flag */
+ uwire_xfer(SSD1783_DEV_ID, SSD1783_UWIRE_BITLEN, &sendcmd, NULL);
+ p++;
+ i++;
+ }
+}
+
+static void
+fb_ssd1783_init(void){
+ printf("%s: initializing LCD.\n",__FUNCTION__);
+ calypso_reset_set(RESET_EXT, 0);
+ delay_ms(5);
+ uwire_init();
+ delay_ms(5);
+ fb_ssd1783_send_cmdlist(ssd1783_initdata);
+}
+
+/* somehow the palette is messed up, RRR seems to have the
+ bits reversed! R0 R1 R2 G G G B B ---> R2 R1 R0 G G G B B */
+static uint8_t fix_rrr(uint8_t v){
+ return (v & 0x5f) | (v & 0x80) >> 2 | (v & 0x20) << 2;
+}
+
+static void
+fb_ssd1783_flush(void){
+ int x,y;
+ uint8_t *p;
+ struct ssd1783_cmdlist prepare_disp_write_cmds[] = {
+ { CMD, 0x15 }, /* set column address */
+ { DATA, fb_rgb332->damage_x1 },
+ { DATA, fb_rgb332->damage_x2-1 },
+ { CMD, 0x75 }, /* set page address (Y) */
+ { DATA, fb_rgb332->damage_y1 },
+ { DATA, fb_rgb332->damage_y2-1 },
+ { CMD, 0x5c }, /* enter write display ram mode */
+ { END, 0x00 }
+ };
+ struct ssd1783_cmdlist nop[] = {
+ { CMD, 0x25 }, // NOP command
+ { END, 0x00 }
+ };
+
+ /* If everything's clean, just return */
+ if(fb_rgb332->damage_x1 == fb_rgb332->damage_x2 ||
+ fb_rgb332->damage_y1 == fb_rgb332->damage_y2){
+ printf("%s: no damage\n",__FUNCTION__);
+ return;
+ }
+
+ fb_ssd1783_send_cmdlist(prepare_disp_write_cmds);
+
+ for(y=fb_rgb332->damage_y1;y<fb_rgb332->damage_y2;y++){
+ p = & fb_rgb332->mem[y * framebuffer->width]; // start of line
+ p += fb_rgb332->damage_x1; // start of damage area
+
+ for(x=fb_rgb332->damage_x1;x<fb_rgb332->damage_x2;x++){
+ uint16_t data = 0x0100 | fix_rrr(*p++); // dummy data
+ uwire_xfer(SSD1783_DEV_ID, SSD1783_UWIRE_BITLEN,
+ &data, NULL);
+ }
+ }
+ fb_ssd1783_send_cmdlist(nop);
+
+ fb_rgb332->damage_x1 = fb_rgb332->damage_x2 = 0;
+ fb_rgb332->damage_y1 = fb_rgb332->damage_y2 = 0;
+}
+
+static struct framebuffer fb_ssd1783_framebuffer = {
+ .name = "ssd1783",
+ .init = fb_ssd1783_init,
+ .clear = fb_rgb332_clear,
+ .boxto = fb_rgb332_boxto,
+ .lineto = fb_rgb332_lineto,
+ .putstr = fb_rgb332_putstr,
+ .flush = fb_ssd1783_flush,
+ .width = SSD1783_WIDTH,
+ .height = SSD1783_HEIGHT
+};
+
+static struct fb_rgb332 fb_ssd1783_rgb332 = {
+ .mem = fb_ssd1783_mem
+};
+
+struct framebuffer *framebuffer = &fb_ssd1783_framebuffer;
+struct fb_rgb332 *fb_rgb332 = &fb_ssd1783_rgb332;
diff --git a/Src/osmolib/src/target/firmware/fb/fb_ssd1963.c b/Src/osmolib/src/target/firmware/fb/fb_ssd1963.c
new file mode 100644
index 0000000..361434e
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_ssd1963.c
@@ -0,0 +1,196 @@
+/* Framebuffer implementation - SSD1963 (S1D15G14 clone) LCD driver for J100i */
+/* Based on ssd1963.c by Steve Markgraf and Harald Welte */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ * (C) 2012 by Steve Markgraf <steve@steve-m.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_rgb332.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <delay.h>
+#include <uwire.h>
+#include <calypso/clock.h>
+
+#define SSD1963_WIDTH 96
+#define SSD1963_HEIGHT 64
+#define SSD1963_UWIRE_BITLEN 9
+#define SSD1963_DEV_ID 0
+
+static uint8_t fb_ssd1963_mem[SSD1963_WIDTH * SSD1963_HEIGHT];
+
+enum ssd1963_cmdflag { CMD, DATA, END };
+
+struct ssd1963_cmdlist {
+ enum ssd1963_cmdflag is_cmd:8; /* 1: is a command, 0: is data, 2: end marker! */
+ uint8_t data; /* 8 bit to send to LC display */
+} __attribute__((packed));
+
+static const struct ssd1963_cmdlist
+ssd1963_initdata[] = {
+ { CMD, 0xb6 }, /* CMD Display Control, set panel parameters */
+ { DATA, 0x4b },
+ { DATA, 0xf1 },
+ { DATA, 0x40 },
+ { DATA, 0x40 },
+ { DATA, 0x00 },
+ { DATA, 0x8c },
+ { DATA, 0x00 },
+ { CMD, 0x3a }, /* CMD Set pixel format */
+ { DATA, 0x02 }, /* DATA: 8 bit per pixel */
+ { CMD, 0x2d }, /* Colour set, RGB332 -> RGB 565 mapping */
+ { DATA, 0x00 }, /* DATA red 000 */
+ { DATA, 0x04 }, /* DATA red 001 */
+ { DATA, 0x09 }, /* DATA red 010 */
+ { DATA, 0x0d }, /* DATA red 011 */
+ { DATA, 0x12 }, /* DATA red 100 */
+ { DATA, 0x16 }, /* DATA red 101 */
+ { DATA, 0x1b }, /* DATA red 110 */
+ { DATA, 0x1f }, /* DATA red 111 */
+ { DATA, 0x00 }, /* Those bytes are probably a second palette */
+ { DATA, 0x00 }, /* for an unused powersaving mode with reduced colors */
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 }, /* DATA green 000 */
+ { DATA, 0x09 }, /* DATA green 001 */
+ { DATA, 0x12 }, /* DATA green 010 */
+ { DATA, 0x1b }, /* DATA green 011 */
+ { DATA, 0x24 }, /* DATA green 100 */
+ { DATA, 0x2d }, /* DATA green 101 */
+ { DATA, 0x36 }, /* DATA green 110 */
+ { DATA, 0x3f }, /* DATA green 111 */
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 }, /* DATA blue 00 */
+ { DATA, 0x0a }, /* DATA blue 01 */
+ { DATA, 0x15 }, /* DATA blue 10 */
+ { DATA, 0x1f }, /* DATA blue 11 */
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { DATA, 0x00 },
+ { CMD, 0x11 }, /* CMD Exit sleep mode*/
+ { CMD, 0xba }, /* CMD Set contrast/Electronic Volume Control */
+ { DATA, 0x5b }, /* DATA: */
+ { DATA, 0x84 }, /* DATA: */
+ { CMD, 0x36 }, /* CMD Memory access control */
+ { DATA, 0x00 }, /* DATA: */
+ { CMD, 0x13 }, /* CMD Enter normal mode */
+ { CMD, 0x29 }, /* CMD Set display on */
+ { END, 0x00 }, /* MARKER: end of list */
+};
+
+static void
+fb_ssd1963_send_cmdlist(const struct ssd1963_cmdlist *p) {
+ int i=0;
+ while(p->is_cmd != END){
+ uint16_t sendcmd = p->data;
+ if(p->is_cmd == DATA)
+ sendcmd |= 0x0100; /* 9th bit is cmd/data flag */
+ uwire_xfer(SSD1963_DEV_ID, SSD1963_UWIRE_BITLEN, &sendcmd, NULL);
+ p++;
+ i++;
+ }
+}
+
+static void
+fb_ssd1963_init(void){
+ printf("%s: initializing LCD.\n",__FUNCTION__);
+ calypso_reset_set(RESET_EXT, 0);
+ delay_ms(5);
+ uwire_init();
+ delay_ms(5);
+ fb_ssd1963_send_cmdlist(ssd1963_initdata);
+}
+
+static void
+fb_ssd1963_flush(void){
+ int x,y;
+ uint8_t *p;
+ struct ssd1963_cmdlist prepare_disp_write_cmds[] = {
+ { CMD, 0x2a }, /* set column address */
+ { DATA, fb_rgb332->damage_x1 },
+ { DATA, fb_rgb332->damage_x2-1 },
+ { CMD, 0x2b }, /* set page address (Y) */
+ { DATA, fb_rgb332->damage_y1 },
+ { DATA, fb_rgb332->damage_y2-1 },
+ { CMD, 0x2c }, /* enter write display ram mode */
+ { END, 0x00 }
+ };
+ struct ssd1963_cmdlist nop[] = {
+ { CMD, 0x00 }, // NOP command
+ { END, 0x00 }
+ };
+
+ /* If everything's clean, just return */
+ if(fb_rgb332->damage_x1 == fb_rgb332->damage_x2 ||
+ fb_rgb332->damage_y1 == fb_rgb332->damage_y2) {
+ printf("%s: no damage\n",__FUNCTION__);
+ return;
+ }
+
+ fb_ssd1963_send_cmdlist(prepare_disp_write_cmds);
+
+ for(y=fb_rgb332->damage_y1;y<fb_rgb332->damage_y2;y++) {
+ p = & fb_rgb332->mem[y * framebuffer->width]; // start of line
+ p += fb_rgb332->damage_x1; // start of damage area
+
+ for(x=fb_rgb332->damage_x1;x<fb_rgb332->damage_x2;x++) {
+ uint16_t data = 0x0100 | *p++;
+ uwire_xfer(SSD1963_DEV_ID, SSD1963_UWIRE_BITLEN,
+ &data, NULL);
+ }
+ }
+ fb_ssd1963_send_cmdlist(nop);
+
+ fb_rgb332->damage_x1 = fb_rgb332->damage_x2 = 0;
+ fb_rgb332->damage_y1 = fb_rgb332->damage_y2 = 0;
+}
+
+static struct framebuffer fb_ssd1963_framebuffer = {
+ .name = "ssd1963",
+ .init = fb_ssd1963_init,
+ .clear = fb_rgb332_clear,
+ .boxto = fb_rgb332_boxto,
+ .lineto = fb_rgb332_lineto,
+ .putstr = fb_rgb332_putstr,
+ .flush = fb_ssd1963_flush,
+ .width = SSD1963_WIDTH,
+ .height = SSD1963_HEIGHT
+};
+
+static struct fb_rgb332 fb_ssd1963_rgb332 = {
+ .mem = fb_ssd1963_mem
+};
+
+struct framebuffer *framebuffer = &fb_ssd1963_framebuffer;
+struct fb_rgb332 *fb_rgb332 = &fb_ssd1963_rgb332;
diff --git a/Src/osmolib/src/target/firmware/fb/fb_st7558.c b/Src/osmolib/src/target/firmware/fb/fb_st7558.c
new file mode 100644
index 0000000..fdcd38f
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_st7558.c
@@ -0,0 +1,132 @@
+/* Framebuffer implementation - ST1783 LCD driver for C123 */
+/* Based on st7558.c by Harald Welte */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_bw8.h>
+
+#include <i2c.h>
+#include <calypso/clock.h>
+#include <delay.h>
+
+#include <stdio.h>
+
+/* Sitronix ST7558 LCD Driver for OSMOCOM framebuffer interface. */
+/* (c) 2010 Christian Vogel <vogelchr@vogel.cx> */
+/* Based on the initial LCD driver by Harald Welte */
+
+#define CONTROL_RS_CMD
+
+#define ST7558_SLAVE_ADDR 0x3c
+#define ST7558_CMD_ADDR 0x00
+#define ST7558_RAM_ADDR 0x40
+
+#define ST7558_WIDTH 96 /* in pixels */
+#define ST7558_HEIGHT 65
+
+#define I2C_MAX_TRANSFER 16
+
+static uint8_t
+fb_st7558_mem[ST7558_WIDTH * ((ST7558_HEIGHT+7)/8)];
+
+/* setup as initially proposed by Harald in st7558.c */
+static const uint8_t st7558_setup[] = {
+ 0x2e, /* ext. display control, set mirror X, set mirror Y*/
+ 0x21, /* function set, enable extended instruction mode */
+ 0x12, /* bias system BS[2,1,0] = [0,1,0] */
+ 0xc0, /* set V_OP (V_OP6 = 1, V_OP[5:0] = 0) */
+ 0x0b, /* booster stages PC1=1, PC0=1 */
+ 0x20, /* function set, disable extended instruction mode */
+ 0x11, /* V_LCD L/H select, PRS=1 */
+ 0x00, /* NOP */
+ 0x0c, /* normal video mode */
+ 0x40, /* set X address to 0 */
+ 0x80 /* set Y address to 0 */
+};
+
+
+static void
+fb_st7558_init(){
+ calypso_reset_set(RESET_EXT, 0);
+ i2c_init(0,0);
+
+ /* initialize controller */
+ i2c_write(ST7558_SLAVE_ADDR,ST7558_CMD_ADDR,1,
+ st7558_setup,sizeof(st7558_setup));
+}
+
+static void
+fb_st7558_flush(){
+ uint16_t x;
+ int page,chunksize,nbytes;
+ uint8_t *p;
+ uint8_t cmd[2];
+
+ if(fb_bw8->damage_y1 == fb_bw8->damage_y2 ||
+ fb_bw8->damage_x1 == fb_bw8->damage_x2)
+ return; /* nothing to update */
+
+ /* update display in stripes of 8 rows, called "pages" */
+ for(page=fb_bw8->damage_y1 >> 3;page <= fb_bw8->damage_y2>>3;page++){
+ /* base offset in RAM framebuffer */
+ x = fb_bw8->damage_x1;
+ nbytes = fb_bw8->damage_x2 - fb_bw8->damage_x1;
+ p = fb_bw8->mem + (page * framebuffer->width + x);
+
+ /* i2c fifo can only handle a maximum of 16 bytes */
+ while(nbytes){
+ cmd[0]=0x40 | page; /* Set Y address of RAM. */
+ cmd[1]=0x80 | x;
+ chunksize = nbytes > I2C_MAX_TRANSFER ? I2C_MAX_TRANSFER : nbytes;
+
+ i2c_write(ST7558_SLAVE_ADDR,ST7558_CMD_ADDR,1,cmd,sizeof(cmd));
+ i2c_write(ST7558_SLAVE_ADDR,ST7558_RAM_ADDR,1,p,chunksize);
+
+ nbytes -= chunksize;
+ p+=I2C_MAX_TRANSFER;
+ x+=I2C_MAX_TRANSFER;
+ }
+ }
+
+ /* mark current buffer as unmodified! */
+ fb_bw8->damage_x1 = fb_bw8->damage_x2 = 0;
+ fb_bw8->damage_y1 = fb_bw8->damage_y2 = 0;
+}
+
+static struct framebuffer fb_st7558_framebuffer = {
+ .name = "st7558",
+ .init = fb_st7558_init,
+ .clear = fb_bw8_clear,
+ .boxto = fb_bw8_boxto,
+ .lineto = fb_bw8_lineto,
+ .putstr = fb_bw8_putstr,
+ .flush = fb_st7558_flush,
+ .width = ST7558_WIDTH,
+ .height = ST7558_HEIGHT
+};
+
+static struct fb_bw8 fb_st7558_bw8 = {
+ .mem = fb_st7558_mem
+};
+
+struct framebuffer *framebuffer = &fb_st7558_framebuffer;
+struct fb_bw8 *fb_bw8 = &fb_st7558_bw8;
diff --git a/Src/osmolib/src/target/firmware/fb/fb_td014.c b/Src/osmolib/src/target/firmware/fb/fb_td014.c
new file mode 100644
index 0000000..c7bde0c
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/fb_td014.c
@@ -0,0 +1,150 @@
+/* Framebuffer implementation - Toppoly TD014 LCD driver for Motorola C139/40 */
+/* Based on td014.c by Steve Markgraf and Harald Welte */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ * (C) 2012 by Steve Markgraf <steve@steve-m.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+#include <fb/fb_rgb332.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <delay.h>
+#include <uwire.h>
+#include <calypso/clock.h>
+
+#define TD014_WIDTH 96
+#define TD014_HEIGHT 64
+#define TD014_UWIRE_BITLEN 9
+#define TD014_DEV_ID 0
+
+static uint8_t fb_td014_mem[TD014_WIDTH * TD014_HEIGHT];
+
+enum td014_cmdflag { CMD, DATA, END };
+
+struct td014_cmdlist {
+ enum td014_cmdflag is_cmd:8; /* 1: is a command, 0: is data, 2: end marker! */
+ uint8_t data; /* 8 bit to send to LC display */
+} __attribute__((packed));
+
+static const struct td014_cmdlist
+td014_initdata[] = {
+ { CMD, 0x3f },
+ { DATA, 0x01 },
+ { CMD, 0x20 },
+ { DATA, 0x03 },
+ { CMD, 0x31 },
+ { DATA, 0x03 },
+ { END, 0x00 }, /* MARKER: end of list */
+};
+
+static void
+fb_td014_send_cmdlist(const struct td014_cmdlist *p) {
+ int i=0;
+ while(p->is_cmd != END){
+ uint16_t sendcmd = p->data;
+ if(p->is_cmd == DATA)
+ sendcmd |= 0x0100; /* 9th bit is cmd/data flag */
+ uwire_xfer(TD014_DEV_ID, TD014_UWIRE_BITLEN, &sendcmd, NULL);
+ p++;
+ i++;
+ }
+}
+
+static void
+fb_td014_init(void) {
+ printf("%s: initializing LCD.\n",__FUNCTION__);
+ calypso_reset_set(RESET_EXT, 0);
+ delay_ms(5);
+ uwire_init();
+ delay_ms(5);
+
+ fb_td014_send_cmdlist(td014_initdata);
+}
+
+static void
+fb_td014_flush(void) {
+ int x,y;
+ uint8_t *p;
+ struct td014_cmdlist prepare_disp_write_cmds[] = {
+ { CMD, 0x10 },
+ { DATA, fb_rgb332->damage_x1 },
+ { CMD, 0x11 },
+ { DATA, fb_rgb332->damage_y1 },
+ { CMD, 0x12 },
+ { DATA, fb_rgb332->damage_x2-1 },
+ { CMD, 0x13 },
+ { DATA, fb_rgb332->damage_y2-1 },
+ { CMD, 0x14 },
+ { DATA, fb_rgb332->damage_x1 },
+ { CMD, 0x15 },
+ { DATA, fb_rgb332->damage_y1 },
+ { END, 0x00 }
+ };
+
+ /* If everything's clean, just return */
+ if(fb_rgb332->damage_x1 == fb_rgb332->damage_x2 ||
+ fb_rgb332->damage_y1 == fb_rgb332->damage_y2) {
+ printf("%s: no damage\n",__FUNCTION__);
+ return;
+ }
+
+ fb_td014_send_cmdlist(prepare_disp_write_cmds);
+
+ for(y=fb_rgb332->damage_y1;y<fb_rgb332->damage_y2;y++) {
+ p = & fb_rgb332->mem[y * framebuffer->width]; // start of line
+ p += fb_rgb332->damage_x1; // start of damage area
+
+ for(x=fb_rgb332->damage_x1; x<fb_rgb332->damage_x2; x++) {
+ uint16_t pixel = rgb332_to_565(*p++);
+ uint16_t data = 0x0100 | (pixel >> 8);
+
+ uwire_xfer(TD014_DEV_ID, TD014_UWIRE_BITLEN,
+ &data, NULL);
+
+ data = 0x0100 | (pixel & 0xff);
+ uwire_xfer(TD014_DEV_ID, TD014_UWIRE_BITLEN,
+ &data, NULL);
+ }
+ }
+
+ fb_rgb332->damage_x1 = fb_rgb332->damage_x2 = 0;
+ fb_rgb332->damage_y1 = fb_rgb332->damage_y2 = 0;
+}
+
+static struct framebuffer fb_td014_framebuffer = {
+ .name = "td014",
+ .init = fb_td014_init,
+ .clear = fb_rgb332_clear,
+ .boxto = fb_rgb332_boxto,
+ .lineto = fb_rgb332_lineto,
+ .putstr = fb_rgb332_putstr,
+ .flush = fb_td014_flush,
+ .width = TD014_WIDTH,
+ .height = TD014_HEIGHT
+};
+
+static struct fb_rgb332 fb_td014_rgb332 = {
+ .mem = fb_td014_mem
+};
+
+struct framebuffer *framebuffer = &fb_td014_framebuffer;
+struct fb_rgb332 *fb_rgb332 = &fb_td014_rgb332;
diff --git a/Src/osmolib/src/target/firmware/fb/font.c b/Src/osmolib/src/target/firmware/fb/font.c
new file mode 100644
index 0000000..d98096f
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/font.c
@@ -0,0 +1,57 @@
+/* Font Handling - Utility Functions */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/font.h>
+
+/* what fonts are linked in? */
+extern const struct fb_font font_4x6;
+extern const struct fb_font font_5x8;
+extern const struct fb_font font_helvR08;
+extern const struct fb_font font_helvR14;
+//extern const struct fb_font font_helvR24;
+//extern const struct fb_font font_helvB08;
+extern const struct fb_font font_helvB14;
+// extern const struct fb_font font_helvB24;
+extern const struct fb_font font_c64;
+
+const struct fb_font *fb_fonts[]={
+// &font_4x6,
+// &font_5x8,
+ &font_helvR08,
+// &font_helvR14,
+// &font_helvR24,
+// &font_helvB08,
+ &font_helvB14,
+// &font_helvB24,
+ &font_c64,
+};
+
+const struct fb_char *
+fb_font_get_char(const struct fb_font *fnt,unsigned char c){
+ if(c < fnt->firstchar || c > fnt->lastchar)
+ return NULL;
+ uint16_t offs = fnt->charoffs[c-fnt->firstchar];
+ if(offs == FB_FONT_NOCHAR)
+ return NULL;
+ return (struct fb_char *)(fnt->chardata + offs);
+}
+
diff --git a/Src/osmolib/src/target/firmware/fb/framebuffer.c b/Src/osmolib/src/target/firmware/fb/framebuffer.c
new file mode 100644
index 0000000..ab54769
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/framebuffer.c
@@ -0,0 +1,28 @@
+/* Framebuffer - Utility Functions */
+
+/* (C) 2010 by Christian Vogel <vogelchr@vogel.cx>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fb/framebuffer.h>
+
+/* currently everything's inline in framebuffer .h */
+
+
+
diff --git a/Src/osmolib/src/target/firmware/fb/helvB08.c b/Src/osmolib/src/target/firmware/fb/helvB08.c
new file mode 100644
index 0000000..97dd92c
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/helvB08.c
@@ -0,0 +1,833 @@
+#include <fb/font.h>
+static const uint8_t font_helvB08_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 2, 1, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 3, 2, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0xc0, /* ##...... */
+ /*000c:*/ 0xc0, /* ##...... */
+ /*000d:*/ 0xc0, /* ##...... */
+ /*000e:*/ 0x80, /* #....... */
+ /*000f:*/ 0x00, /* ........ */
+ /*0010:*/ 0x80, /* #....... */
+ /*0011:*/ 0x80, /* #....... */
+/* --- new character quotedbl (34) starting at offset 0x0012 --- */
+ /*0012:*/ 4, 3, 2, 0, 4, /* width and bbox (w,h,x,y) */
+ /*0017:*/ 0xa0, /* #.#..... */
+ /*0018:*/ 0xa0, /* #.#..... */
+/* --- new character numbersign (35) starting at offset 0x0019 --- */
+ /*0019:*/ 5, 5, 6, -1, 0, /* width and bbox (w,h,x,y) */
+ /*001e:*/ 0x50, /* .#.#.... */
+ /*001f:*/ 0xf8, /* #####... */
+ /*0020:*/ 0x50, /* .#.#.... */
+ /*0021:*/ 0xf8, /* #####... */
+ /*0022:*/ 0xa0, /* #.#..... */
+ /*0023:*/ 0xa0, /* #.#..... */
+/* --- new character dollar (36) starting at offset 0x0024 --- */
+ /*0024:*/ 5, 4, 8, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0029:*/ 0x20, /* ..#..... */
+ /*002a:*/ 0x70, /* .###.... */
+ /*002b:*/ 0xc0, /* ##...... */
+ /*002c:*/ 0xe0, /* ###..... */
+ /*002d:*/ 0x70, /* .###.... */
+ /*002e:*/ 0x30, /* ..##.... */
+ /*002f:*/ 0xe0, /* ###..... */
+ /*0030:*/ 0x40, /* .#...... */
+/* --- new character percent (37) starting at offset 0x0031 --- */
+ /*0031:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0036:*/ 0x68, /* .##.#... */
+ /*0037:*/ 0xb0, /* #.##.... */
+ /*0038:*/ 0xe0, /* ###..... */
+ /*0039:*/ 0x38, /* ..###... */
+ /*003a:*/ 0x68, /* .##.#... */
+ /*003b:*/ 0xb0, /* #.##.... */
+/* --- new character ampersand (38) starting at offset 0x003c --- */
+ /*003c:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0041:*/ 0x70, /* .###.... */
+ /*0042:*/ 0x50, /* .#.#.... */
+ /*0043:*/ 0x60, /* .##..... */
+ /*0044:*/ 0xf8, /* #####... */
+ /*0045:*/ 0xd0, /* ##.#.... */
+ /*0046:*/ 0x68, /* .##.#... */
+/* --- new character quotesingle (39) starting at offset 0x0047 --- */
+ /*0047:*/ 3, 1, 3, 1, 5, /* width and bbox (w,h,x,y) */
+ /*004c:*/ 0x80, /* #....... */
+ /*004d:*/ 0x80, /* #....... */
+ /*004e:*/ 0x80, /* #....... */
+/* --- new character parenleft (40) starting at offset 0x004f --- */
+ /*004f:*/ 3, 2, 8, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0054:*/ 0x40, /* .#...... */
+ /*0055:*/ 0x40, /* .#...... */
+ /*0056:*/ 0x80, /* #....... */
+ /*0057:*/ 0x80, /* #....... */
+ /*0058:*/ 0x80, /* #....... */
+ /*0059:*/ 0x80, /* #....... */
+ /*005a:*/ 0x40, /* .#...... */
+ /*005b:*/ 0x40, /* .#...... */
+/* --- new character parenright (41) starting at offset 0x005c --- */
+ /*005c:*/ 3, 2, 8, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0061:*/ 0x80, /* #....... */
+ /*0062:*/ 0x80, /* #....... */
+ /*0063:*/ 0x40, /* .#...... */
+ /*0064:*/ 0x40, /* .#...... */
+ /*0065:*/ 0x40, /* .#...... */
+ /*0066:*/ 0x40, /* .#...... */
+ /*0067:*/ 0x80, /* #....... */
+ /*0068:*/ 0x80, /* #....... */
+/* --- new character asterisk (42) starting at offset 0x0069 --- */
+ /*0069:*/ 3, 3, 3, 0, 3, /* width and bbox (w,h,x,y) */
+ /*006e:*/ 0x40, /* .#...... */
+ /*006f:*/ 0xe0, /* ###..... */
+ /*0070:*/ 0x40, /* .#...... */
+/* --- new character plus (43) starting at offset 0x0071 --- */
+ /*0071:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0076:*/ 0x20, /* ..#..... */
+ /*0077:*/ 0x20, /* ..#..... */
+ /*0078:*/ 0xf0, /* ####.... */
+ /*0079:*/ 0x20, /* ..#..... */
+ /*007a:*/ 0x20, /* ..#..... */
+/* --- new character comma (44) starting at offset 0x007b --- */
+ /*007b:*/ 2, 2, 3, -1, -1, /* width and bbox (w,h,x,y) */
+ /*0080:*/ 0x40, /* .#...... */
+ /*0081:*/ 0x40, /* .#...... */
+ /*0082:*/ 0x80, /* #....... */
+/* --- new character hyphen (45) starting at offset 0x0083 --- */
+ /*0083:*/ 4, 3, 1, 0, 2, /* width and bbox (w,h,x,y) */
+ /*0088:*/ 0xe0, /* ###..... */
+/* --- new character period (46) starting at offset 0x0089 --- */
+ /*0089:*/ 2, 1, 2, 0, 0, /* width and bbox (w,h,x,y) */
+ /*008e:*/ 0x80, /* #....... */
+ /*008f:*/ 0x80, /* #....... */
+/* --- new character slash (47) starting at offset 0x0090 --- */
+ /*0090:*/ 3, 3, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0095:*/ 0x20, /* ..#..... */
+ /*0096:*/ 0x20, /* ..#..... */
+ /*0097:*/ 0x40, /* .#...... */
+ /*0098:*/ 0x40, /* .#...... */
+ /*0099:*/ 0x80, /* #....... */
+ /*009a:*/ 0x80, /* #....... */
+/* --- new character zero (48) starting at offset 0x009b --- */
+ /*009b:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00a0:*/ 0x60, /* .##..... */
+ /*00a1:*/ 0xd0, /* ##.#.... */
+ /*00a2:*/ 0xd0, /* ##.#.... */
+ /*00a3:*/ 0xd0, /* ##.#.... */
+ /*00a4:*/ 0xd0, /* ##.#.... */
+ /*00a5:*/ 0x60, /* .##..... */
+/* --- new character one (49) starting at offset 0x00a6 --- */
+ /*00a6:*/ 5, 3, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00ab:*/ 0x20, /* ..#..... */
+ /*00ac:*/ 0xe0, /* ###..... */
+ /*00ad:*/ 0x60, /* .##..... */
+ /*00ae:*/ 0x60, /* .##..... */
+ /*00af:*/ 0x60, /* .##..... */
+ /*00b0:*/ 0x60, /* .##..... */
+/* --- new character two (50) starting at offset 0x00b1 --- */
+ /*00b1:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00b6:*/ 0x60, /* .##..... */
+ /*00b7:*/ 0xb0, /* #.##.... */
+ /*00b8:*/ 0x30, /* ..##.... */
+ /*00b9:*/ 0x60, /* .##..... */
+ /*00ba:*/ 0xc0, /* ##...... */
+ /*00bb:*/ 0xf0, /* ####.... */
+/* --- new character three (51) starting at offset 0x00bc --- */
+ /*00bc:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00c1:*/ 0x60, /* .##..... */
+ /*00c2:*/ 0xb0, /* #.##.... */
+ /*00c3:*/ 0x60, /* .##..... */
+ /*00c4:*/ 0x30, /* ..##.... */
+ /*00c5:*/ 0xb0, /* #.##.... */
+ /*00c6:*/ 0x60, /* .##..... */
+/* --- new character four (52) starting at offset 0x00c7 --- */
+ /*00c7:*/ 5, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00cc:*/ 0x30, /* ..##.... */
+ /*00cd:*/ 0x50, /* .#.#.... */
+ /*00ce:*/ 0xd0, /* ##.#.... */
+ /*00cf:*/ 0xf8, /* #####... */
+ /*00d0:*/ 0x30, /* ..##.... */
+ /*00d1:*/ 0x30, /* ..##.... */
+/* --- new character five (53) starting at offset 0x00d2 --- */
+ /*00d2:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00d7:*/ 0x70, /* .###.... */
+ /*00d8:*/ 0xc0, /* ##...... */
+ /*00d9:*/ 0xe0, /* ###..... */
+ /*00da:*/ 0x30, /* ..##.... */
+ /*00db:*/ 0xb0, /* #.##.... */
+ /*00dc:*/ 0x60, /* .##..... */
+/* --- new character six (54) starting at offset 0x00dd --- */
+ /*00dd:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00e2:*/ 0x70, /* .###.... */
+ /*00e3:*/ 0xc0, /* ##...... */
+ /*00e4:*/ 0xe0, /* ###..... */
+ /*00e5:*/ 0xd0, /* ##.#.... */
+ /*00e6:*/ 0xd0, /* ##.#.... */
+ /*00e7:*/ 0x60, /* .##..... */
+/* --- new character seven (55) starting at offset 0x00e8 --- */
+ /*00e8:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00ed:*/ 0xf0, /* ####.... */
+ /*00ee:*/ 0x30, /* ..##.... */
+ /*00ef:*/ 0x30, /* ..##.... */
+ /*00f0:*/ 0x60, /* .##..... */
+ /*00f1:*/ 0x40, /* .#...... */
+ /*00f2:*/ 0xc0, /* ##...... */
+/* --- new character eight (56) starting at offset 0x00f3 --- */
+ /*00f3:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00f8:*/ 0x60, /* .##..... */
+ /*00f9:*/ 0xd0, /* ##.#.... */
+ /*00fa:*/ 0x60, /* .##..... */
+ /*00fb:*/ 0xd0, /* ##.#.... */
+ /*00fc:*/ 0xd0, /* ##.#.... */
+ /*00fd:*/ 0x60, /* .##..... */
+/* --- new character nine (57) starting at offset 0x00fe --- */
+ /*00fe:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0103:*/ 0x60, /* .##..... */
+ /*0104:*/ 0xb0, /* #.##.... */
+ /*0105:*/ 0xb0, /* #.##.... */
+ /*0106:*/ 0x70, /* .###.... */
+ /*0107:*/ 0x30, /* ..##.... */
+ /*0108:*/ 0xe0, /* ###..... */
+/* --- new character colon (58) starting at offset 0x0109 --- */
+ /*0109:*/ 2, 1, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*010e:*/ 0x80, /* #....... */
+ /*010f:*/ 0x80, /* #....... */
+ /*0110:*/ 0x00, /* ........ */
+ /*0111:*/ 0x80, /* #....... */
+ /*0112:*/ 0x80, /* #....... */
+/* --- new character semicolon (59) starting at offset 0x0113 --- */
+ /*0113:*/ 2, 2, 6, -1, -1, /* width and bbox (w,h,x,y) */
+ /*0118:*/ 0x40, /* .#...... */
+ /*0119:*/ 0x40, /* .#...... */
+ /*011a:*/ 0x00, /* ........ */
+ /*011b:*/ 0x40, /* .#...... */
+ /*011c:*/ 0x40, /* .#...... */
+ /*011d:*/ 0x80, /* #....... */
+/* --- new character less (60) starting at offset 0x011e --- */
+ /*011e:*/ 4, 3, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0123:*/ 0x20, /* ..#..... */
+ /*0124:*/ 0x40, /* .#...... */
+ /*0125:*/ 0x80, /* #....... */
+ /*0126:*/ 0x40, /* .#...... */
+ /*0127:*/ 0x20, /* ..#..... */
+/* --- new character equal (61) starting at offset 0x0128 --- */
+ /*0128:*/ 5, 4, 3, 0, 1, /* width and bbox (w,h,x,y) */
+ /*012d:*/ 0xf0, /* ####.... */
+ /*012e:*/ 0x00, /* ........ */
+ /*012f:*/ 0xf0, /* ####.... */
+/* --- new character greater (62) starting at offset 0x0130 --- */
+ /*0130:*/ 4, 3, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0135:*/ 0x80, /* #....... */
+ /*0136:*/ 0x40, /* .#...... */
+ /*0137:*/ 0x20, /* ..#..... */
+ /*0138:*/ 0x40, /* .#...... */
+ /*0139:*/ 0x80, /* #....... */
+/* --- new character question (63) starting at offset 0x013a --- */
+ /*013a:*/ 5, 4, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*013f:*/ 0xe0, /* ###..... */
+ /*0140:*/ 0x30, /* ..##.... */
+ /*0141:*/ 0x60, /* .##..... */
+ /*0142:*/ 0x40, /* .#...... */
+ /*0143:*/ 0x00, /* ........ */
+ /*0144:*/ 0x40, /* .#...... */
+ /*0145:*/ 0x40, /* .#...... */
+/* --- new character at (64) starting at offset 0x0146 --- */
+ /*0146:*/ 9, 8, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*014b:*/ 0x7e, /* .######. */
+ /*014c:*/ 0xc3, /* ##....## */
+ /*014d:*/ 0x99, /* #..##..# */
+ /*014e:*/ 0xa9, /* #.#.#..# */
+ /*014f:*/ 0x99, /* #..##..# */
+ /*0150:*/ 0xce, /* ##..###. */
+ /*0151:*/ 0x60, /* .##..... */
+/* --- new character A (65) starting at offset 0x0152 --- */
+ /*0152:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0157:*/ 0x70, /* .###.... */
+ /*0158:*/ 0xd8, /* ##.##... */
+ /*0159:*/ 0xd8, /* ##.##... */
+ /*015a:*/ 0xf8, /* #####... */
+ /*015b:*/ 0xd8, /* ##.##... */
+ /*015c:*/ 0xd8, /* ##.##... */
+/* --- new character B (66) starting at offset 0x015d --- */
+ /*015d:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0162:*/ 0xf0, /* ####.... */
+ /*0163:*/ 0xd8, /* ##.##... */
+ /*0164:*/ 0xf0, /* ####.... */
+ /*0165:*/ 0xd8, /* ##.##... */
+ /*0166:*/ 0xd8, /* ##.##... */
+ /*0167:*/ 0xf0, /* ####.... */
+/* --- new character C (67) starting at offset 0x0168 --- */
+ /*0168:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*016d:*/ 0x78, /* .####... */
+ /*016e:*/ 0xc8, /* ##..#... */
+ /*016f:*/ 0xc0, /* ##...... */
+ /*0170:*/ 0xc0, /* ##...... */
+ /*0171:*/ 0xc8, /* ##..#... */
+ /*0172:*/ 0x78, /* .####... */
+/* --- new character D (68) starting at offset 0x0173 --- */
+ /*0173:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0178:*/ 0xf0, /* ####.... */
+ /*0179:*/ 0xd8, /* ##.##... */
+ /*017a:*/ 0xd8, /* ##.##... */
+ /*017b:*/ 0xd8, /* ##.##... */
+ /*017c:*/ 0xd8, /* ##.##... */
+ /*017d:*/ 0xf0, /* ####.... */
+/* --- new character E (69) starting at offset 0x017e --- */
+ /*017e:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0183:*/ 0xf0, /* ####.... */
+ /*0184:*/ 0xc0, /* ##...... */
+ /*0185:*/ 0xf0, /* ####.... */
+ /*0186:*/ 0xc0, /* ##...... */
+ /*0187:*/ 0xc0, /* ##...... */
+ /*0188:*/ 0xf0, /* ####.... */
+/* --- new character F (70) starting at offset 0x0189 --- */
+ /*0189:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*018e:*/ 0xf0, /* ####.... */
+ /*018f:*/ 0xc0, /* ##...... */
+ /*0190:*/ 0xf0, /* ####.... */
+ /*0191:*/ 0xc0, /* ##...... */
+ /*0192:*/ 0xc0, /* ##...... */
+ /*0193:*/ 0xc0, /* ##...... */
+/* --- new character G (71) starting at offset 0x0194 --- */
+ /*0194:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0199:*/ 0x78, /* .####... */
+ /*019a:*/ 0xc8, /* ##..#... */
+ /*019b:*/ 0xc0, /* ##...... */
+ /*019c:*/ 0xd8, /* ##.##... */
+ /*019d:*/ 0xc8, /* ##..#... */
+ /*019e:*/ 0x78, /* .####... */
+/* --- new character H (72) starting at offset 0x019f --- */
+ /*019f:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01a4:*/ 0xd8, /* ##.##... */
+ /*01a5:*/ 0xd8, /* ##.##... */
+ /*01a6:*/ 0xf8, /* #####... */
+ /*01a7:*/ 0xd8, /* ##.##... */
+ /*01a8:*/ 0xd8, /* ##.##... */
+ /*01a9:*/ 0xd8, /* ##.##... */
+/* --- new character I (73) starting at offset 0x01aa --- */
+ /*01aa:*/ 2, 1, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01af:*/ 0x80, /* #....... */
+ /*01b0:*/ 0x80, /* #....... */
+ /*01b1:*/ 0x80, /* #....... */
+ /*01b2:*/ 0x80, /* #....... */
+ /*01b3:*/ 0x80, /* #....... */
+ /*01b4:*/ 0x80, /* #....... */
+/* --- new character J (74) starting at offset 0x01b5 --- */
+ /*01b5:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01ba:*/ 0x30, /* ..##.... */
+ /*01bb:*/ 0x30, /* ..##.... */
+ /*01bc:*/ 0x30, /* ..##.... */
+ /*01bd:*/ 0x30, /* ..##.... */
+ /*01be:*/ 0xb0, /* #.##.... */
+ /*01bf:*/ 0x60, /* .##..... */
+/* --- new character K (75) starting at offset 0x01c0 --- */
+ /*01c0:*/ 6, 6, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01c5:*/ 0xd8, /* ##.##... */
+ /*01c6:*/ 0xd0, /* ##.#.... */
+ /*01c7:*/ 0xe0, /* ###..... */
+ /*01c8:*/ 0xf0, /* ####.... */
+ /*01c9:*/ 0xd8, /* ##.##... */
+ /*01ca:*/ 0xcc, /* ##..##.. */
+/* --- new character L (76) starting at offset 0x01cb --- */
+ /*01cb:*/ 5, 4, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01d0:*/ 0xc0, /* ##...... */
+ /*01d1:*/ 0xc0, /* ##...... */
+ /*01d2:*/ 0xc0, /* ##...... */
+ /*01d3:*/ 0xc0, /* ##...... */
+ /*01d4:*/ 0xc0, /* ##...... */
+ /*01d5:*/ 0xf0, /* ####.... */
+/* --- new character M (77) starting at offset 0x01d6 --- */
+ /*01d6:*/ 8, 7, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01db:*/ 0xc6, /* ##...##. */
+ /*01dc:*/ 0xc6, /* ##...##. */
+ /*01dd:*/ 0xee, /* ###.###. */
+ /*01de:*/ 0xfe, /* #######. */
+ /*01df:*/ 0xd6, /* ##.#.##. */
+ /*01e0:*/ 0xd6, /* ##.#.##. */
+/* --- new character N (78) starting at offset 0x01e1 --- */
+ /*01e1:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01e6:*/ 0xc8, /* ##..#... */
+ /*01e7:*/ 0xc8, /* ##..#... */
+ /*01e8:*/ 0xe8, /* ###.#... */
+ /*01e9:*/ 0xf8, /* #####... */
+ /*01ea:*/ 0xd8, /* ##.##... */
+ /*01eb:*/ 0xc8, /* ##..#... */
+/* --- new character O (79) starting at offset 0x01ec --- */
+ /*01ec:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01f1:*/ 0x70, /* .###.... */
+ /*01f2:*/ 0xd8, /* ##.##... */
+ /*01f3:*/ 0xc8, /* ##..#... */
+ /*01f4:*/ 0xc8, /* ##..#... */
+ /*01f5:*/ 0xd8, /* ##.##... */
+ /*01f6:*/ 0x70, /* .###.... */
+/* --- new character P (80) starting at offset 0x01f7 --- */
+ /*01f7:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01fc:*/ 0xf0, /* ####.... */
+ /*01fd:*/ 0xd8, /* ##.##... */
+ /*01fe:*/ 0xd8, /* ##.##... */
+ /*01ff:*/ 0xf0, /* ####.... */
+ /*0200:*/ 0xc0, /* ##...... */
+ /*0201:*/ 0xc0, /* ##...... */
+/* --- new character Q (81) starting at offset 0x0202 --- */
+ /*0202:*/ 6, 6, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0207:*/ 0x70, /* .###.... */
+ /*0208:*/ 0xd8, /* ##.##... */
+ /*0209:*/ 0xc8, /* ##..#... */
+ /*020a:*/ 0xc8, /* ##..#... */
+ /*020b:*/ 0xd8, /* ##.##... */
+ /*020c:*/ 0x78, /* .####... */
+ /*020d:*/ 0x04, /* .....#.. */
+/* --- new character R (82) starting at offset 0x020e --- */
+ /*020e:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0213:*/ 0xf0, /* ####.... */
+ /*0214:*/ 0xd8, /* ##.##... */
+ /*0215:*/ 0xd8, /* ##.##... */
+ /*0216:*/ 0xf0, /* ####.... */
+ /*0217:*/ 0xd8, /* ##.##... */
+ /*0218:*/ 0xd8, /* ##.##... */
+/* --- new character S (83) starting at offset 0x0219 --- */
+ /*0219:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*021e:*/ 0x78, /* .####... */
+ /*021f:*/ 0xc0, /* ##...... */
+ /*0220:*/ 0xf0, /* ####.... */
+ /*0221:*/ 0x38, /* ..###... */
+ /*0222:*/ 0xd8, /* ##.##... */
+ /*0223:*/ 0x70, /* .###.... */
+/* --- new character T (84) starting at offset 0x0224 --- */
+ /*0224:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0229:*/ 0xf8, /* #####... */
+ /*022a:*/ 0x60, /* .##..... */
+ /*022b:*/ 0x60, /* .##..... */
+ /*022c:*/ 0x60, /* .##..... */
+ /*022d:*/ 0x60, /* .##..... */
+ /*022e:*/ 0x60, /* .##..... */
+/* --- new character U (85) starting at offset 0x022f --- */
+ /*022f:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0234:*/ 0xd8, /* ##.##... */
+ /*0235:*/ 0xd8, /* ##.##... */
+ /*0236:*/ 0xd8, /* ##.##... */
+ /*0237:*/ 0xd8, /* ##.##... */
+ /*0238:*/ 0xd8, /* ##.##... */
+ /*0239:*/ 0x70, /* .###.... */
+/* --- new character V (86) starting at offset 0x023a --- */
+ /*023a:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*023f:*/ 0xe8, /* ###.#... */
+ /*0240:*/ 0x68, /* .##.#... */
+ /*0241:*/ 0x68, /* .##.#... */
+ /*0242:*/ 0x68, /* .##.#... */
+ /*0243:*/ 0x70, /* .###.... */
+ /*0244:*/ 0x20, /* ..#..... */
+/* --- new character W (87) starting at offset 0x0245 --- */
+ /*0245:*/ 9, 8, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*024a:*/ 0xdb, /* ##.##.## */
+ /*024b:*/ 0xdb, /* ##.##.## */
+ /*024c:*/ 0xda, /* ##.##.#. */
+ /*024d:*/ 0xda, /* ##.##.#. */
+ /*024e:*/ 0x6c, /* .##.##.. */
+ /*024f:*/ 0x6c, /* .##.##.. */
+/* --- new character X (88) starting at offset 0x0250 --- */
+ /*0250:*/ 6, 5, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0255:*/ 0xd8, /* ##.##... */
+ /*0256:*/ 0xd8, /* ##.##... */
+ /*0257:*/ 0x70, /* .###.... */
+ /*0258:*/ 0x70, /* .###.... */
+ /*0259:*/ 0xd8, /* ##.##... */
+ /*025a:*/ 0xd8, /* ##.##... */
+/* --- new character Y (89) starting at offset 0x025b --- */
+ /*025b:*/ 7, 6, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0260:*/ 0xec, /* ###.##.. */
+ /*0261:*/ 0x68, /* .##.#... */
+ /*0262:*/ 0x68, /* .##.#... */
+ /*0263:*/ 0x78, /* .####... */
+ /*0264:*/ 0x30, /* ..##.... */
+ /*0265:*/ 0x30, /* ..##.... */
+/* --- new character Z (90) starting at offset 0x0266 --- */
+ /*0266:*/ 6, 6, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*026b:*/ 0xfc, /* ######.. */
+ /*026c:*/ 0x38, /* ..###... */
+ /*026d:*/ 0x30, /* ..##.... */
+ /*026e:*/ 0x60, /* .##..... */
+ /*026f:*/ 0xe0, /* ###..... */
+ /*0270:*/ 0xf8, /* #####... */
+/* --- new character bracketleft (91) starting at offset 0x0271 --- */
+ /*0271:*/ 3, 2, 8, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0276:*/ 0xc0, /* ##...... */
+ /*0277:*/ 0x80, /* #....... */
+ /*0278:*/ 0x80, /* #....... */
+ /*0279:*/ 0x80, /* #....... */
+ /*027a:*/ 0x80, /* #....... */
+ /*027b:*/ 0x80, /* #....... */
+ /*027c:*/ 0x80, /* #....... */
+ /*027d:*/ 0xc0, /* ##...... */
+/* --- new character backslash (92) starting at offset 0x027e --- */
+ /*027e:*/ 3, 3, 6, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0283:*/ 0x80, /* #....... */
+ /*0284:*/ 0x80, /* #....... */
+ /*0285:*/ 0x40, /* .#...... */
+ /*0286:*/ 0x40, /* .#...... */
+ /*0287:*/ 0x20, /* ..#..... */
+ /*0288:*/ 0x20, /* ..#..... */
+/* --- new character bracketright (93) starting at offset 0x0289 --- */
+ /*0289:*/ 3, 2, 8, 0, -2, /* width and bbox (w,h,x,y) */
+ /*028e:*/ 0xc0, /* ##...... */
+ /*028f:*/ 0x40, /* .#...... */
+ /*0290:*/ 0x40, /* .#...... */
+ /*0291:*/ 0x40, /* .#...... */
+ /*0292:*/ 0x40, /* .#...... */
+ /*0293:*/ 0x40, /* .#...... */
+ /*0294:*/ 0x40, /* .#...... */
+ /*0295:*/ 0xc0, /* ##...... */
+/* --- new character asciicircum (94) starting at offset 0x0296 --- */
+ /*0296:*/ 4, 4, 3, 0, 3, /* width and bbox (w,h,x,y) */
+ /*029b:*/ 0x60, /* .##..... */
+ /*029c:*/ 0x60, /* .##..... */
+ /*029d:*/ 0x90, /* #..#.... */
+/* --- new character underscore (95) starting at offset 0x029e --- */
+ /*029e:*/ 5, 5, 1, 0, -1, /* width and bbox (w,h,x,y) */
+ /*02a3:*/ 0xf8, /* #####... */
+/* --- new character grave (96) starting at offset 0x02a4 --- */
+ /*02a4:*/ 3, 2, 2, 0, 6, /* width and bbox (w,h,x,y) */
+ /*02a9:*/ 0x80, /* #....... */
+ /*02aa:*/ 0x40, /* .#...... */
+/* --- new character a (97) starting at offset 0x02ab --- */
+ /*02ab:*/ 5, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02b0:*/ 0xe0, /* ###..... */
+ /*02b1:*/ 0x30, /* ..##.... */
+ /*02b2:*/ 0xf0, /* ####.... */
+ /*02b3:*/ 0xb0, /* #.##.... */
+ /*02b4:*/ 0xd8, /* ##.##... */
+/* --- new character b (98) starting at offset 0x02b5 --- */
+ /*02b5:*/ 5, 4, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02ba:*/ 0xc0, /* ##...... */
+ /*02bb:*/ 0xc0, /* ##...... */
+ /*02bc:*/ 0xe0, /* ###..... */
+ /*02bd:*/ 0xd0, /* ##.#.... */
+ /*02be:*/ 0xd0, /* ##.#.... */
+ /*02bf:*/ 0xd0, /* ##.#.... */
+ /*02c0:*/ 0xe0, /* ###..... */
+/* --- new character c (99) starting at offset 0x02c1 --- */
+ /*02c1:*/ 4, 3, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02c6:*/ 0x60, /* .##..... */
+ /*02c7:*/ 0xc0, /* ##...... */
+ /*02c8:*/ 0xc0, /* ##...... */
+ /*02c9:*/ 0xc0, /* ##...... */
+ /*02ca:*/ 0x60, /* .##..... */
+/* --- new character d (100) starting at offset 0x02cb --- */
+ /*02cb:*/ 5, 4, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02d0:*/ 0x30, /* ..##.... */
+ /*02d1:*/ 0x30, /* ..##.... */
+ /*02d2:*/ 0x70, /* .###.... */
+ /*02d3:*/ 0xb0, /* #.##.... */
+ /*02d4:*/ 0xb0, /* #.##.... */
+ /*02d5:*/ 0xb0, /* #.##.... */
+ /*02d6:*/ 0x70, /* .###.... */
+/* --- new character e (101) starting at offset 0x02d7 --- */
+ /*02d7:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02dc:*/ 0x60, /* .##..... */
+ /*02dd:*/ 0xd0, /* ##.#.... */
+ /*02de:*/ 0xf0, /* ####.... */
+ /*02df:*/ 0xc0, /* ##...... */
+ /*02e0:*/ 0x60, /* .##..... */
+/* --- new character f (102) starting at offset 0x02e1 --- */
+ /*02e1:*/ 3, 4, 7, -1, 0, /* width and bbox (w,h,x,y) */
+ /*02e6:*/ 0x30, /* ..##.... */
+ /*02e7:*/ 0x60, /* .##..... */
+ /*02e8:*/ 0xf0, /* ####.... */
+ /*02e9:*/ 0x60, /* .##..... */
+ /*02ea:*/ 0x60, /* .##..... */
+ /*02eb:*/ 0x60, /* .##..... */
+ /*02ec:*/ 0x60, /* .##..... */
+/* --- new character g (103) starting at offset 0x02ed --- */
+ /*02ed:*/ 5, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*02f2:*/ 0xd0, /* ##.#.... */
+ /*02f3:*/ 0xb0, /* #.##.... */
+ /*02f4:*/ 0xb0, /* #.##.... */
+ /*02f5:*/ 0xf0, /* ####.... */
+ /*02f6:*/ 0x30, /* ..##.... */
+ /*02f7:*/ 0xe0, /* ###..... */
+/* --- new character h (104) starting at offset 0x02f8 --- */
+ /*02f8:*/ 5, 4, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02fd:*/ 0xc0, /* ##...... */
+ /*02fe:*/ 0xc0, /* ##...... */
+ /*02ff:*/ 0xe0, /* ###..... */
+ /*0300:*/ 0xd0, /* ##.#.... */
+ /*0301:*/ 0xd0, /* ##.#.... */
+ /*0302:*/ 0xd0, /* ##.#.... */
+ /*0303:*/ 0xd0, /* ##.#.... */
+/* --- new character i (105) starting at offset 0x0304 --- */
+ /*0304:*/ 2, 1, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0309:*/ 0x80, /* #....... */
+ /*030a:*/ 0x00, /* ........ */
+ /*030b:*/ 0x80, /* #....... */
+ /*030c:*/ 0x80, /* #....... */
+ /*030d:*/ 0x80, /* #....... */
+ /*030e:*/ 0x80, /* #....... */
+ /*030f:*/ 0x80, /* #....... */
+/* --- new character j (106) starting at offset 0x0310 --- */
+ /*0310:*/ 2, 2, 8, -1, -1, /* width and bbox (w,h,x,y) */
+ /*0315:*/ 0x40, /* .#...... */
+ /*0316:*/ 0x00, /* ........ */
+ /*0317:*/ 0x40, /* .#...... */
+ /*0318:*/ 0x40, /* .#...... */
+ /*0319:*/ 0x40, /* .#...... */
+ /*031a:*/ 0x40, /* .#...... */
+ /*031b:*/ 0x40, /* .#...... */
+ /*031c:*/ 0x80, /* #....... */
+/* --- new character k (107) starting at offset 0x031d --- */
+ /*031d:*/ 5, 4, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0322:*/ 0xc0, /* ##...... */
+ /*0323:*/ 0xc0, /* ##...... */
+ /*0324:*/ 0xd0, /* ##.#.... */
+ /*0325:*/ 0xd0, /* ##.#.... */
+ /*0326:*/ 0xe0, /* ###..... */
+ /*0327:*/ 0xd0, /* ##.#.... */
+ /*0328:*/ 0xd0, /* ##.#.... */
+/* --- new character l (108) starting at offset 0x0329 --- */
+ /*0329:*/ 2, 1, 7, 0, 0, /* width and bbox (w,h,x,y) */
+ /*032e:*/ 0x80, /* #....... */
+ /*032f:*/ 0x80, /* #....... */
+ /*0330:*/ 0x80, /* #....... */
+ /*0331:*/ 0x80, /* #....... */
+ /*0332:*/ 0x80, /* #....... */
+ /*0333:*/ 0x80, /* #....... */
+ /*0334:*/ 0x80, /* #....... */
+/* --- new character m (109) starting at offset 0x0335 --- */
+ /*0335:*/ 7, 6, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*033a:*/ 0xe8, /* ###.#... */
+ /*033b:*/ 0xd4, /* ##.#.#.. */
+ /*033c:*/ 0xd4, /* ##.#.#.. */
+ /*033d:*/ 0xd4, /* ##.#.#.. */
+ /*033e:*/ 0xd4, /* ##.#.#.. */
+/* --- new character n (110) starting at offset 0x033f --- */
+ /*033f:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0344:*/ 0xe0, /* ###..... */
+ /*0345:*/ 0xd0, /* ##.#.... */
+ /*0346:*/ 0xd0, /* ##.#.... */
+ /*0347:*/ 0xd0, /* ##.#.... */
+ /*0348:*/ 0xd0, /* ##.#.... */
+/* --- new character o (111) starting at offset 0x0349 --- */
+ /*0349:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*034e:*/ 0x60, /* .##..... */
+ /*034f:*/ 0xd0, /* ##.#.... */
+ /*0350:*/ 0xd0, /* ##.#.... */
+ /*0351:*/ 0xd0, /* ##.#.... */
+ /*0352:*/ 0x60, /* .##..... */
+/* --- new character p (112) starting at offset 0x0353 --- */
+ /*0353:*/ 5, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0358:*/ 0xe0, /* ###..... */
+ /*0359:*/ 0xd0, /* ##.#.... */
+ /*035a:*/ 0xd0, /* ##.#.... */
+ /*035b:*/ 0xd0, /* ##.#.... */
+ /*035c:*/ 0xe0, /* ###..... */
+ /*035d:*/ 0xc0, /* ##...... */
+/* --- new character q (113) starting at offset 0x035e --- */
+ /*035e:*/ 5, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0363:*/ 0x70, /* .###.... */
+ /*0364:*/ 0xb0, /* #.##.... */
+ /*0365:*/ 0xb0, /* #.##.... */
+ /*0366:*/ 0xb0, /* #.##.... */
+ /*0367:*/ 0x70, /* .###.... */
+ /*0368:*/ 0x30, /* ..##.... */
+/* --- new character r (114) starting at offset 0x0369 --- */
+ /*0369:*/ 3, 3, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*036e:*/ 0xa0, /* #.#..... */
+ /*036f:*/ 0xe0, /* ###..... */
+ /*0370:*/ 0xc0, /* ##...... */
+ /*0371:*/ 0xc0, /* ##...... */
+ /*0372:*/ 0xc0, /* ##...... */
+/* --- new character s (115) starting at offset 0x0373 --- */
+ /*0373:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0378:*/ 0x70, /* .###.... */
+ /*0379:*/ 0xc0, /* ##...... */
+ /*037a:*/ 0xf0, /* ####.... */
+ /*037b:*/ 0x30, /* ..##.... */
+ /*037c:*/ 0xe0, /* ###..... */
+/* --- new character t (116) starting at offset 0x037d --- */
+ /*037d:*/ 3, 4, 7, -1, 0, /* width and bbox (w,h,x,y) */
+ /*0382:*/ 0x20, /* ..#..... */
+ /*0383:*/ 0x60, /* .##..... */
+ /*0384:*/ 0xf0, /* ####.... */
+ /*0385:*/ 0x60, /* .##..... */
+ /*0386:*/ 0x60, /* .##..... */
+ /*0387:*/ 0x60, /* .##..... */
+ /*0388:*/ 0x30, /* ..##.... */
+/* --- new character u (117) starting at offset 0x0389 --- */
+ /*0389:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*038e:*/ 0xd0, /* ##.#.... */
+ /*038f:*/ 0xd0, /* ##.#.... */
+ /*0390:*/ 0xd0, /* ##.#.... */
+ /*0391:*/ 0xf0, /* ####.... */
+ /*0392:*/ 0x50, /* .#.#.... */
+/* --- new character v (118) starting at offset 0x0393 --- */
+ /*0393:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0398:*/ 0xd0, /* ##.#.... */
+ /*0399:*/ 0xd0, /* ##.#.... */
+ /*039a:*/ 0xd0, /* ##.#.... */
+ /*039b:*/ 0x60, /* .##..... */
+ /*039c:*/ 0x40, /* .#...... */
+/* --- new character w (119) starting at offset 0x039d --- */
+ /*039d:*/ 6, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03a2:*/ 0xa8, /* #.#.#... */
+ /*03a3:*/ 0xa8, /* #.#.#... */
+ /*03a4:*/ 0xf8, /* #####... */
+ /*03a5:*/ 0xf8, /* #####... */
+ /*03a6:*/ 0x48, /* .#..#... */
+/* --- new character x (120) starting at offset 0x03a7 --- */
+ /*03a7:*/ 6, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03ac:*/ 0xd8, /* ##.##... */
+ /*03ad:*/ 0xd8, /* ##.##... */
+ /*03ae:*/ 0x70, /* .###.... */
+ /*03af:*/ 0xd8, /* ##.##... */
+ /*03b0:*/ 0xd8, /* ##.##... */
+/* --- new character y (121) starting at offset 0x03b1 --- */
+ /*03b1:*/ 5, 4, 6, 0, -1, /* width and bbox (w,h,x,y) */
+ /*03b6:*/ 0xd0, /* ##.#.... */
+ /*03b7:*/ 0xd0, /* ##.#.... */
+ /*03b8:*/ 0xd0, /* ##.#.... */
+ /*03b9:*/ 0x70, /* .###.... */
+ /*03ba:*/ 0x60, /* .##..... */
+ /*03bb:*/ 0x60, /* .##..... */
+/* --- new character z (122) starting at offset 0x03bc --- */
+ /*03bc:*/ 5, 4, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03c1:*/ 0xf0, /* ####.... */
+ /*03c2:*/ 0x30, /* ..##.... */
+ /*03c3:*/ 0x60, /* .##..... */
+ /*03c4:*/ 0xc0, /* ##...... */
+ /*03c5:*/ 0xf0, /* ####.... */
+/* --- new character braceleft (123) starting at offset 0x03c6 --- */
+ /*03c6:*/ 4, 3, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*03cb:*/ 0x20, /* ..#..... */
+ /*03cc:*/ 0x40, /* .#...... */
+ /*03cd:*/ 0x40, /* .#...... */
+ /*03ce:*/ 0x80, /* #....... */
+ /*03cf:*/ 0x40, /* .#...... */
+ /*03d0:*/ 0x40, /* .#...... */
+ /*03d1:*/ 0x20, /* ..#..... */
+/* --- new character bar (124) starting at offset 0x03d2 --- */
+ /*03d2:*/ 2, 1, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*03d7:*/ 0x80, /* #....... */
+ /*03d8:*/ 0x80, /* #....... */
+ /*03d9:*/ 0x80, /* #....... */
+ /*03da:*/ 0x80, /* #....... */
+ /*03db:*/ 0x80, /* #....... */
+ /*03dc:*/ 0x80, /* #....... */
+ /*03dd:*/ 0x80, /* #....... */
+/* --- new character braceright (125) starting at offset 0x03de --- */
+ /*03de:*/ 4, 3, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*03e3:*/ 0x80, /* #....... */
+ /*03e4:*/ 0x40, /* .#...... */
+ /*03e5:*/ 0x40, /* .#...... */
+ /*03e6:*/ 0x20, /* ..#..... */
+ /*03e7:*/ 0x40, /* .#...... */
+ /*03e8:*/ 0x40, /* .#...... */
+ /*03e9:*/ 0x80, /* #....... */
+/* --- new character asciitilde (126) starting at offset 0x03ea --- */
+ /*03ea:*/ 5, 5, 2, 0, 2, /* width and bbox (w,h,x,y) */
+ /*03ef:*/ 0x58, /* .#.##... */
+ /*03f0:*/ 0xb0, /* #.##.... */
+};
+static const uint16_t font_helvB08_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x0012 /* quotedbl */,
+ 0x0019 /* numbersign */,
+ 0x0024 /* dollar */,
+ 0x0031 /* percent */,
+ 0x003c /* ampersand */,
+ 0x0047 /* quotesingle */,
+ 0x004f /* parenleft */,
+ 0x005c /* parenright */,
+ 0x0069 /* asterisk */,
+ 0x0071 /* plus */,
+ 0x007b /* comma */,
+ 0x0083 /* hyphen */,
+ 0x0089 /* period */,
+ 0x0090 /* slash */,
+ 0x009b /* zero */,
+ 0x00a6 /* one */,
+ 0x00b1 /* two */,
+ 0x00bc /* three */,
+ 0x00c7 /* four */,
+ 0x00d2 /* five */,
+ 0x00dd /* six */,
+ 0x00e8 /* seven */,
+ 0x00f3 /* eight */,
+ 0x00fe /* nine */,
+ 0x0109 /* colon */,
+ 0x0113 /* semicolon */,
+ 0x011e /* less */,
+ 0x0128 /* equal */,
+ 0x0130 /* greater */,
+ 0x013a /* question */,
+ 0x0146 /* at */,
+ 0x0152 /* A */,
+ 0x015d /* B */,
+ 0x0168 /* C */,
+ 0x0173 /* D */,
+ 0x017e /* E */,
+ 0x0189 /* F */,
+ 0x0194 /* G */,
+ 0x019f /* H */,
+ 0x01aa /* I */,
+ 0x01b5 /* J */,
+ 0x01c0 /* K */,
+ 0x01cb /* L */,
+ 0x01d6 /* M */,
+ 0x01e1 /* N */,
+ 0x01ec /* O */,
+ 0x01f7 /* P */,
+ 0x0202 /* Q */,
+ 0x020e /* R */,
+ 0x0219 /* S */,
+ 0x0224 /* T */,
+ 0x022f /* U */,
+ 0x023a /* V */,
+ 0x0245 /* W */,
+ 0x0250 /* X */,
+ 0x025b /* Y */,
+ 0x0266 /* Z */,
+ 0x0271 /* bracketleft */,
+ 0x027e /* backslash */,
+ 0x0289 /* bracketright */,
+ 0x0296 /* asciicircum */,
+ 0x029e /* underscore */,
+ 0x02a4 /* grave */,
+ 0x02ab /* a */,
+ 0x02b5 /* b */,
+ 0x02c1 /* c */,
+ 0x02cb /* d */,
+ 0x02d7 /* e */,
+ 0x02e1 /* f */,
+ 0x02ed /* g */,
+ 0x02f8 /* h */,
+ 0x0304 /* i */,
+ 0x0310 /* j */,
+ 0x031d /* k */,
+ 0x0329 /* l */,
+ 0x0335 /* m */,
+ 0x033f /* n */,
+ 0x0349 /* o */,
+ 0x0353 /* p */,
+ 0x035e /* q */,
+ 0x0369 /* r */,
+ 0x0373 /* s */,
+ 0x037d /* t */,
+ 0x0389 /* u */,
+ 0x0393 /* v */,
+ 0x039d /* w */,
+ 0x03a7 /* x */,
+ 0x03b1 /* y */,
+ 0x03bc /* z */,
+ 0x03c6 /* braceleft */,
+ 0x03d2 /* bar */,
+ 0x03de /* braceright */,
+ 0x03ea /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_helvB08 = {
+ .height = 10,
+ .ascent = 8,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_helvB08_data,
+ .charoffs = font_helvB08_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/helvB14.c b/Src/osmolib/src/target/firmware/fb/helvB14.c
new file mode 100644
index 0000000..40c310e
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/helvB14.c
@@ -0,0 +1,1195 @@
+#include <fb/font.h>
+static const uint8_t font_helvB14_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 4, 1, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 4, 2, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0xc0, /* ##...... */
+ /*000c:*/ 0xc0, /* ##...... */
+ /*000d:*/ 0xc0, /* ##...... */
+ /*000e:*/ 0xc0, /* ##...... */
+ /*000f:*/ 0xc0, /* ##...... */
+ /*0010:*/ 0xc0, /* ##...... */
+ /*0011:*/ 0x80, /* #....... */
+ /*0012:*/ 0x80, /* #....... */
+ /*0013:*/ 0x00, /* ........ */
+ /*0014:*/ 0xc0, /* ##...... */
+ /*0015:*/ 0xc0, /* ##...... */
+/* --- new character quotedbl (34) starting at offset 0x0016 --- */
+ /*0016:*/ 7, 5, 3, 1, 8, /* width and bbox (w,h,x,y) */
+ /*001b:*/ 0xd8, /* ##.##... */
+ /*001c:*/ 0xd8, /* ##.##... */
+ /*001d:*/ 0x90, /* #..#.... */
+/* --- new character numbersign (35) starting at offset 0x001e --- */
+ /*001e:*/ 9, 9, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0023:*/ 0x1b,0x00, /* ...##.##........ */
+ /*0025:*/ 0x1b,0x00, /* ...##.##........ */
+ /*0027:*/ 0x1b,0x00, /* ...##.##........ */
+ /*0029:*/ 0x7f,0x80, /* .########....... */
+ /*002b:*/ 0x36,0x00, /* ..##.##......... */
+ /*002d:*/ 0x36,0x00, /* ..##.##......... */
+ /*002f:*/ 0xff,0x00, /* ########........ */
+ /*0031:*/ 0x6c,0x00, /* .##.##.......... */
+ /*0033:*/ 0x6c,0x00, /* .##.##.......... */
+ /*0035:*/ 0x6c,0x00, /* .##.##.......... */
+/* --- new character dollar (36) starting at offset 0x0037 --- */
+ /*0037:*/ 8, 7, 13, 0, -2, /* width and bbox (w,h,x,y) */
+ /*003c:*/ 0x10, /* ...#.... */
+ /*003d:*/ 0x7c, /* .#####.. */
+ /*003e:*/ 0xd6, /* ##.#.##. */
+ /*003f:*/ 0xd6, /* ##.#.##. */
+ /*0040:*/ 0xf0, /* ####.... */
+ /*0041:*/ 0x78, /* .####... */
+ /*0042:*/ 0x1c, /* ...###.. */
+ /*0043:*/ 0x16, /* ...#.##. */
+ /*0044:*/ 0xd6, /* ##.#.##. */
+ /*0045:*/ 0xd6, /* ##.#.##. */
+ /*0046:*/ 0x7c, /* .#####.. */
+ /*0047:*/ 0x10, /* ...#.... */
+ /*0048:*/ 0x10, /* ...#.... */
+/* --- new character percent (37) starting at offset 0x0049 --- */
+ /*0049:*/ 13, 12, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*004e:*/ 0x78,0x80, /* .####...#....... */
+ /*0050:*/ 0xcd,0x80, /* ##..##.##....... */
+ /*0052:*/ 0xcd,0x00, /* ##..##.#........ */
+ /*0054:*/ 0x7b,0x00, /* .####.##........ */
+ /*0056:*/ 0x06,0x00, /* .....##......... */
+ /*0058:*/ 0x04,0x00, /* .....#.......... */
+ /*005a:*/ 0x0d,0xe0, /* ....##.####..... */
+ /*005c:*/ 0x0b,0x30, /* ....#.##..##.... */
+ /*005e:*/ 0x1b,0x30, /* ...##.##..##.... */
+ /*0060:*/ 0x11,0xe0, /* ...#...####..... */
+/* --- new character ampersand (38) starting at offset 0x0062 --- */
+ /*0062:*/ 11, 9, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0067:*/ 0x38,0x00, /* ..###........... */
+ /*0069:*/ 0x6c,0x00, /* .##.##.......... */
+ /*006b:*/ 0x6c,0x00, /* .##.##.......... */
+ /*006d:*/ 0x38,0x00, /* ..###........... */
+ /*006f:*/ 0x73,0x00, /* .###..##........ */
+ /*0071:*/ 0xfb,0x00, /* #####.##........ */
+ /*0073:*/ 0xce,0x00, /* ##..###......... */
+ /*0075:*/ 0xc6,0x00, /* ##...##......... */
+ /*0077:*/ 0xcf,0x00, /* ##..####........ */
+ /*0079:*/ 0x7d,0x80, /* .#####.##....... */
+/* --- new character quotesingle (39) starting at offset 0x007b --- */
+ /*007b:*/ 4, 2, 3, 1, 8, /* width and bbox (w,h,x,y) */
+ /*0080:*/ 0xc0, /* ##...... */
+ /*0081:*/ 0xc0, /* ##...... */
+ /*0082:*/ 0x80, /* #....... */
+/* --- new character parenleft (40) starting at offset 0x0083 --- */
+ /*0083:*/ 5, 4, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*0088:*/ 0x30, /* ..##.... */
+ /*0089:*/ 0x60, /* .##..... */
+ /*008a:*/ 0x60, /* .##..... */
+ /*008b:*/ 0xc0, /* ##...... */
+ /*008c:*/ 0xc0, /* ##...... */
+ /*008d:*/ 0xc0, /* ##...... */
+ /*008e:*/ 0xc0, /* ##...... */
+ /*008f:*/ 0xc0, /* ##...... */
+ /*0090:*/ 0xc0, /* ##...... */
+ /*0091:*/ 0xc0, /* ##...... */
+ /*0092:*/ 0xc0, /* ##...... */
+ /*0093:*/ 0x60, /* .##..... */
+ /*0094:*/ 0x60, /* .##..... */
+ /*0095:*/ 0x30, /* ..##.... */
+/* --- new character parenright (41) starting at offset 0x0096 --- */
+ /*0096:*/ 5, 4, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*009b:*/ 0xc0, /* ##...... */
+ /*009c:*/ 0x60, /* .##..... */
+ /*009d:*/ 0x60, /* .##..... */
+ /*009e:*/ 0x30, /* ..##.... */
+ /*009f:*/ 0x30, /* ..##.... */
+ /*00a0:*/ 0x30, /* ..##.... */
+ /*00a1:*/ 0x30, /* ..##.... */
+ /*00a2:*/ 0x30, /* ..##.... */
+ /*00a3:*/ 0x30, /* ..##.... */
+ /*00a4:*/ 0x30, /* ..##.... */
+ /*00a5:*/ 0x30, /* ..##.... */
+ /*00a6:*/ 0x60, /* .##..... */
+ /*00a7:*/ 0x60, /* .##..... */
+ /*00a8:*/ 0xc0, /* ##...... */
+/* --- new character asterisk (42) starting at offset 0x00a9 --- */
+ /*00a9:*/ 6, 5, 4, 0, 7, /* width and bbox (w,h,x,y) */
+ /*00ae:*/ 0x20, /* ..#..... */
+ /*00af:*/ 0xf8, /* #####... */
+ /*00b0:*/ 0x70, /* .###.... */
+ /*00b1:*/ 0xd8, /* ##.##... */
+/* --- new character plus (43) starting at offset 0x00b2 --- */
+ /*00b2:*/ 9, 8, 7, 0, 1, /* width and bbox (w,h,x,y) */
+ /*00b7:*/ 0x18, /* ...##... */
+ /*00b8:*/ 0x18, /* ...##... */
+ /*00b9:*/ 0x18, /* ...##... */
+ /*00ba:*/ 0xff, /* ######## */
+ /*00bb:*/ 0x18, /* ...##... */
+ /*00bc:*/ 0x18, /* ...##... */
+ /*00bd:*/ 0x18, /* ...##... */
+/* --- new character comma (44) starting at offset 0x00be --- */
+ /*00be:*/ 4, 3, 3, 0, -1, /* width and bbox (w,h,x,y) */
+ /*00c3:*/ 0x60, /* .##..... */
+ /*00c4:*/ 0x60, /* .##..... */
+ /*00c5:*/ 0xc0, /* ##...... */
+/* --- new character hyphen (45) starting at offset 0x00c6 --- */
+ /*00c6:*/ 5, 5, 1, 0, 4, /* width and bbox (w,h,x,y) */
+ /*00cb:*/ 0xf8, /* #####... */
+/* --- new character period (46) starting at offset 0x00cc --- */
+ /*00cc:*/ 4, 2, 2, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00d1:*/ 0xc0, /* ##...... */
+ /*00d2:*/ 0xc0, /* ##...... */
+/* --- new character slash (47) starting at offset 0x00d3 --- */
+ /*00d3:*/ 4, 4, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00d8:*/ 0x30, /* ..##.... */
+ /*00d9:*/ 0x30, /* ..##.... */
+ /*00da:*/ 0x20, /* ..#..... */
+ /*00db:*/ 0x20, /* ..#..... */
+ /*00dc:*/ 0x60, /* .##..... */
+ /*00dd:*/ 0x60, /* .##..... */
+ /*00de:*/ 0x60, /* .##..... */
+ /*00df:*/ 0x40, /* .#...... */
+ /*00e0:*/ 0x40, /* .#...... */
+ /*00e1:*/ 0xc0, /* ##...... */
+ /*00e2:*/ 0xc0, /* ##...... */
+/* --- new character zero (48) starting at offset 0x00e3 --- */
+ /*00e3:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00e8:*/ 0x38, /* ..###... */
+ /*00e9:*/ 0x6c, /* .##.##.. */
+ /*00ea:*/ 0xc6, /* ##...##. */
+ /*00eb:*/ 0xc6, /* ##...##. */
+ /*00ec:*/ 0xc6, /* ##...##. */
+ /*00ed:*/ 0xc6, /* ##...##. */
+ /*00ee:*/ 0xc6, /* ##...##. */
+ /*00ef:*/ 0xc6, /* ##...##. */
+ /*00f0:*/ 0x6c, /* .##.##.. */
+ /*00f1:*/ 0x38, /* ..###... */
+/* --- new character one (49) starting at offset 0x00f2 --- */
+ /*00f2:*/ 8, 4, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00f7:*/ 0x30, /* ..##.... */
+ /*00f8:*/ 0xf0, /* ####.... */
+ /*00f9:*/ 0x30, /* ..##.... */
+ /*00fa:*/ 0x30, /* ..##.... */
+ /*00fb:*/ 0x30, /* ..##.... */
+ /*00fc:*/ 0x30, /* ..##.... */
+ /*00fd:*/ 0x30, /* ..##.... */
+ /*00fe:*/ 0x30, /* ..##.... */
+ /*00ff:*/ 0x30, /* ..##.... */
+ /*0100:*/ 0x30, /* ..##.... */
+/* --- new character two (50) starting at offset 0x0101 --- */
+ /*0101:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0106:*/ 0x7c, /* .#####.. */
+ /*0107:*/ 0xe6, /* ###..##. */
+ /*0108:*/ 0xc6, /* ##...##. */
+ /*0109:*/ 0x0e, /* ....###. */
+ /*010a:*/ 0x0c, /* ....##.. */
+ /*010b:*/ 0x38, /* ..###... */
+ /*010c:*/ 0x70, /* .###.... */
+ /*010d:*/ 0xe0, /* ###..... */
+ /*010e:*/ 0xc0, /* ##...... */
+ /*010f:*/ 0xfe, /* #######. */
+/* --- new character three (51) starting at offset 0x0110 --- */
+ /*0110:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0115:*/ 0x7c, /* .#####.. */
+ /*0116:*/ 0xce, /* ##..###. */
+ /*0117:*/ 0xc6, /* ##...##. */
+ /*0118:*/ 0x06, /* .....##. */
+ /*0119:*/ 0x3c, /* ..####.. */
+ /*011a:*/ 0x06, /* .....##. */
+ /*011b:*/ 0x06, /* .....##. */
+ /*011c:*/ 0xc6, /* ##...##. */
+ /*011d:*/ 0xce, /* ##..###. */
+ /*011e:*/ 0x7c, /* .#####.. */
+/* --- new character four (52) starting at offset 0x011f --- */
+ /*011f:*/ 8, 8, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0124:*/ 0x0e, /* ....###. */
+ /*0125:*/ 0x1e, /* ...####. */
+ /*0126:*/ 0x36, /* ..##.##. */
+ /*0127:*/ 0x66, /* .##..##. */
+ /*0128:*/ 0xc6, /* ##...##. */
+ /*0129:*/ 0xc6, /* ##...##. */
+ /*012a:*/ 0xff, /* ######## */
+ /*012b:*/ 0x06, /* .....##. */
+ /*012c:*/ 0x06, /* .....##. */
+ /*012d:*/ 0x06, /* .....##. */
+/* --- new character five (53) starting at offset 0x012e --- */
+ /*012e:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0133:*/ 0x7e, /* .######. */
+ /*0134:*/ 0x60, /* .##..... */
+ /*0135:*/ 0xc0, /* ##...... */
+ /*0136:*/ 0xf8, /* #####... */
+ /*0137:*/ 0x1c, /* ...###.. */
+ /*0138:*/ 0x06, /* .....##. */
+ /*0139:*/ 0x06, /* .....##. */
+ /*013a:*/ 0xc6, /* ##...##. */
+ /*013b:*/ 0xec, /* ###.##.. */
+ /*013c:*/ 0x78, /* .####... */
+/* --- new character six (54) starting at offset 0x013d --- */
+ /*013d:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0142:*/ 0x3c, /* ..####.. */
+ /*0143:*/ 0x76, /* .###.##. */
+ /*0144:*/ 0x66, /* .##..##. */
+ /*0145:*/ 0xc0, /* ##...... */
+ /*0146:*/ 0xdc, /* ##.###.. */
+ /*0147:*/ 0xf6, /* ####.##. */
+ /*0148:*/ 0xc6, /* ##...##. */
+ /*0149:*/ 0xc6, /* ##...##. */
+ /*014a:*/ 0x6e, /* .##.###. */
+ /*014b:*/ 0x3c, /* ..####.. */
+/* --- new character seven (55) starting at offset 0x014c --- */
+ /*014c:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0151:*/ 0xfe, /* #######. */
+ /*0152:*/ 0x06, /* .....##. */
+ /*0153:*/ 0x0c, /* ....##.. */
+ /*0154:*/ 0x0c, /* ....##.. */
+ /*0155:*/ 0x18, /* ...##... */
+ /*0156:*/ 0x18, /* ...##... */
+ /*0157:*/ 0x30, /* ..##.... */
+ /*0158:*/ 0x30, /* ..##.... */
+ /*0159:*/ 0x60, /* .##..... */
+ /*015a:*/ 0x60, /* .##..... */
+/* --- new character eight (56) starting at offset 0x015b --- */
+ /*015b:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0160:*/ 0x7c, /* .#####.. */
+ /*0161:*/ 0xee, /* ###.###. */
+ /*0162:*/ 0xc6, /* ##...##. */
+ /*0163:*/ 0xc6, /* ##...##. */
+ /*0164:*/ 0x7c, /* .#####.. */
+ /*0165:*/ 0xee, /* ###.###. */
+ /*0166:*/ 0xc6, /* ##...##. */
+ /*0167:*/ 0xc6, /* ##...##. */
+ /*0168:*/ 0xc6, /* ##...##. */
+ /*0169:*/ 0x7c, /* .#####.. */
+/* --- new character nine (57) starting at offset 0x016a --- */
+ /*016a:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*016f:*/ 0x7c, /* .#####.. */
+ /*0170:*/ 0xee, /* ###.###. */
+ /*0171:*/ 0xc6, /* ##...##. */
+ /*0172:*/ 0xc6, /* ##...##. */
+ /*0173:*/ 0xe6, /* ###..##. */
+ /*0174:*/ 0x7e, /* .######. */
+ /*0175:*/ 0x06, /* .....##. */
+ /*0176:*/ 0xc6, /* ##...##. */
+ /*0177:*/ 0xce, /* ##..###. */
+ /*0178:*/ 0x7c, /* .#####.. */
+/* --- new character colon (58) starting at offset 0x0179 --- */
+ /*0179:*/ 5, 2, 8, 2, 0, /* width and bbox (w,h,x,y) */
+ /*017e:*/ 0xc0, /* ##...... */
+ /*017f:*/ 0xc0, /* ##...... */
+ /*0180:*/ 0x00, /* ........ */
+ /*0181:*/ 0x00, /* ........ */
+ /*0182:*/ 0x00, /* ........ */
+ /*0183:*/ 0x00, /* ........ */
+ /*0184:*/ 0xc0, /* ##...... */
+ /*0185:*/ 0xc0, /* ##...... */
+/* --- new character semicolon (59) starting at offset 0x0186 --- */
+ /*0186:*/ 5, 3, 9, 1, -1, /* width and bbox (w,h,x,y) */
+ /*018b:*/ 0x60, /* .##..... */
+ /*018c:*/ 0x60, /* .##..... */
+ /*018d:*/ 0x00, /* ........ */
+ /*018e:*/ 0x00, /* ........ */
+ /*018f:*/ 0x00, /* ........ */
+ /*0190:*/ 0x00, /* ........ */
+ /*0191:*/ 0x60, /* .##..... */
+ /*0192:*/ 0x60, /* .##..... */
+ /*0193:*/ 0xc0, /* ##...... */
+/* --- new character less (60) starting at offset 0x0194 --- */
+ /*0194:*/ 8, 6, 5, 1, 2, /* width and bbox (w,h,x,y) */
+ /*0199:*/ 0x1c, /* ...###.. */
+ /*019a:*/ 0x70, /* .###.... */
+ /*019b:*/ 0xc0, /* ##...... */
+ /*019c:*/ 0x70, /* .###.... */
+ /*019d:*/ 0x1c, /* ...###.. */
+/* --- new character equal (61) starting at offset 0x019e --- */
+ /*019e:*/ 9, 7, 3, 1, 3, /* width and bbox (w,h,x,y) */
+ /*01a3:*/ 0xfe, /* #######. */
+ /*01a4:*/ 0x00, /* ........ */
+ /*01a5:*/ 0xfe, /* #######. */
+/* --- new character greater (62) starting at offset 0x01a6 --- */
+ /*01a6:*/ 8, 6, 5, 1, 2, /* width and bbox (w,h,x,y) */
+ /*01ab:*/ 0xe0, /* ###..... */
+ /*01ac:*/ 0x38, /* ..###... */
+ /*01ad:*/ 0x0c, /* ....##.. */
+ /*01ae:*/ 0x38, /* ..###... */
+ /*01af:*/ 0xe0, /* ###..... */
+/* --- new character question (63) starting at offset 0x01b0 --- */
+ /*01b0:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01b5:*/ 0x7c, /* .#####.. */
+ /*01b6:*/ 0xc6, /* ##...##. */
+ /*01b7:*/ 0xc6, /* ##...##. */
+ /*01b8:*/ 0x06, /* .....##. */
+ /*01b9:*/ 0x0c, /* ....##.. */
+ /*01ba:*/ 0x18, /* ...##... */
+ /*01bb:*/ 0x30, /* ..##.... */
+ /*01bc:*/ 0x30, /* ..##.... */
+ /*01bd:*/ 0x00, /* ........ */
+ /*01be:*/ 0x30, /* ..##.... */
+ /*01bf:*/ 0x30, /* ..##.... */
+/* --- new character at (64) starting at offset 0x01c0 --- */
+ /*01c0:*/ 14, 13, 12, 0, -1, /* width and bbox (w,h,x,y) */
+ /*01c5:*/ 0x0f,0x80, /* ....#####....... */
+ /*01c7:*/ 0x38,0xe0, /* ..###...###..... */
+ /*01c9:*/ 0x70,0x70, /* .###.....###.... */
+ /*01cb:*/ 0x66,0xb0, /* .##..##.#.##.... */
+ /*01cd:*/ 0xcd,0x98, /* ##..##.##..##... */
+ /*01cf:*/ 0xd9,0x98, /* ##.##..##..##... */
+ /*01d1:*/ 0xdb,0x18, /* ##.##.##...##... */
+ /*01d3:*/ 0xdb,0x30, /* ##.##.##..##.... */
+ /*01d5:*/ 0xce,0xe0, /* ##..###.###..... */
+ /*01d7:*/ 0x60,0x00, /* .##............. */
+ /*01d9:*/ 0x31,0x80, /* ..##...##....... */
+ /*01db:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character A (65) starting at offset 0x01dd --- */
+ /*01dd:*/ 10, 10, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01e2:*/ 0x0c,0x00, /* ....##.......... */
+ /*01e4:*/ 0x0c,0x00, /* ....##.......... */
+ /*01e6:*/ 0x1e,0x00, /* ...####......... */
+ /*01e8:*/ 0x12,0x00, /* ...#..#......... */
+ /*01ea:*/ 0x33,0x00, /* ..##..##........ */
+ /*01ec:*/ 0x33,0x00, /* ..##..##........ */
+ /*01ee:*/ 0x61,0x80, /* .##....##....... */
+ /*01f0:*/ 0x7f,0x80, /* .########....... */
+ /*01f2:*/ 0x61,0x80, /* .##....##....... */
+ /*01f4:*/ 0xc0,0xc0, /* ##......##...... */
+ /*01f6:*/ 0xc0,0xc0, /* ##......##...... */
+/* --- new character B (66) starting at offset 0x01f8 --- */
+ /*01f8:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01fd:*/ 0xfe, /* #######. */
+ /*01fe:*/ 0xc7, /* ##...### */
+ /*01ff:*/ 0xc3, /* ##....## */
+ /*0200:*/ 0xc3, /* ##....## */
+ /*0201:*/ 0xc6, /* ##...##. */
+ /*0202:*/ 0xfc, /* ######.. */
+ /*0203:*/ 0xc6, /* ##...##. */
+ /*0204:*/ 0xc3, /* ##....## */
+ /*0205:*/ 0xc3, /* ##....## */
+ /*0206:*/ 0xc7, /* ##...### */
+ /*0207:*/ 0xfe, /* #######. */
+/* --- new character C (67) starting at offset 0x0208 --- */
+ /*0208:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*020d:*/ 0x1f,0x00, /* ...#####........ */
+ /*020f:*/ 0x7b,0x80, /* .####.###....... */
+ /*0211:*/ 0x60,0x80, /* .##.....#....... */
+ /*0213:*/ 0xc0,0x00, /* ##.............. */
+ /*0215:*/ 0xc0,0x00, /* ##.............. */
+ /*0217:*/ 0xc0,0x00, /* ##.............. */
+ /*0219:*/ 0xc0,0x00, /* ##.............. */
+ /*021b:*/ 0xc0,0x00, /* ##.............. */
+ /*021d:*/ 0x60,0x80, /* .##.....#....... */
+ /*021f:*/ 0x7b,0x80, /* .####.###....... */
+ /*0221:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character D (68) starting at offset 0x0223 --- */
+ /*0223:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0228:*/ 0xfc,0x00, /* ######.......... */
+ /*022a:*/ 0xc7,0x00, /* ##...###........ */
+ /*022c:*/ 0xc3,0x00, /* ##....##........ */
+ /*022e:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0230:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0232:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0234:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0236:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0238:*/ 0xc3,0x00, /* ##....##........ */
+ /*023a:*/ 0xc7,0x00, /* ##...###........ */
+ /*023c:*/ 0xfc,0x00, /* ######.......... */
+/* --- new character E (69) starting at offset 0x023e --- */
+ /*023e:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0243:*/ 0xfe, /* #######. */
+ /*0244:*/ 0xc0, /* ##...... */
+ /*0245:*/ 0xc0, /* ##...... */
+ /*0246:*/ 0xc0, /* ##...... */
+ /*0247:*/ 0xc0, /* ##...... */
+ /*0248:*/ 0xfe, /* #######. */
+ /*0249:*/ 0xc0, /* ##...... */
+ /*024a:*/ 0xc0, /* ##...... */
+ /*024b:*/ 0xc0, /* ##...... */
+ /*024c:*/ 0xc0, /* ##...... */
+ /*024d:*/ 0xfe, /* #######. */
+/* --- new character F (70) starting at offset 0x024e --- */
+ /*024e:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0253:*/ 0xfe, /* #######. */
+ /*0254:*/ 0xc0, /* ##...... */
+ /*0255:*/ 0xc0, /* ##...... */
+ /*0256:*/ 0xc0, /* ##...... */
+ /*0257:*/ 0xc0, /* ##...... */
+ /*0258:*/ 0xfc, /* ######.. */
+ /*0259:*/ 0xc0, /* ##...... */
+ /*025a:*/ 0xc0, /* ##...... */
+ /*025b:*/ 0xc0, /* ##...... */
+ /*025c:*/ 0xc0, /* ##...... */
+ /*025d:*/ 0xc0, /* ##...... */
+/* --- new character G (71) starting at offset 0x025e --- */
+ /*025e:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0263:*/ 0x1f,0x00, /* ...#####........ */
+ /*0265:*/ 0x7b,0x80, /* .####.###....... */
+ /*0267:*/ 0x60,0x80, /* .##.....#....... */
+ /*0269:*/ 0xc0,0x00, /* ##.............. */
+ /*026b:*/ 0xc0,0x00, /* ##.............. */
+ /*026d:*/ 0xc7,0x80, /* ##...####....... */
+ /*026f:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0271:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0273:*/ 0x61,0x80, /* .##....##....... */
+ /*0275:*/ 0x7b,0x80, /* .####.###....... */
+ /*0277:*/ 0x1e,0x80, /* ...####.#....... */
+/* --- new character H (72) starting at offset 0x0279 --- */
+ /*0279:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*027e:*/ 0xc3, /* ##....## */
+ /*027f:*/ 0xc3, /* ##....## */
+ /*0280:*/ 0xc3, /* ##....## */
+ /*0281:*/ 0xc3, /* ##....## */
+ /*0282:*/ 0xc3, /* ##....## */
+ /*0283:*/ 0xff, /* ######## */
+ /*0284:*/ 0xc3, /* ##....## */
+ /*0285:*/ 0xc3, /* ##....## */
+ /*0286:*/ 0xc3, /* ##....## */
+ /*0287:*/ 0xc3, /* ##....## */
+ /*0288:*/ 0xc3, /* ##....## */
+/* --- new character I (73) starting at offset 0x0289 --- */
+ /*0289:*/ 4, 2, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*028e:*/ 0xc0, /* ##...... */
+ /*028f:*/ 0xc0, /* ##...... */
+ /*0290:*/ 0xc0, /* ##...... */
+ /*0291:*/ 0xc0, /* ##...... */
+ /*0292:*/ 0xc0, /* ##...... */
+ /*0293:*/ 0xc0, /* ##...... */
+ /*0294:*/ 0xc0, /* ##...... */
+ /*0295:*/ 0xc0, /* ##...... */
+ /*0296:*/ 0xc0, /* ##...... */
+ /*0297:*/ 0xc0, /* ##...... */
+ /*0298:*/ 0xc0, /* ##...... */
+/* --- new character J (74) starting at offset 0x0299 --- */
+ /*0299:*/ 8, 7, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*029e:*/ 0x06, /* .....##. */
+ /*029f:*/ 0x06, /* .....##. */
+ /*02a0:*/ 0x06, /* .....##. */
+ /*02a1:*/ 0x06, /* .....##. */
+ /*02a2:*/ 0x06, /* .....##. */
+ /*02a3:*/ 0x06, /* .....##. */
+ /*02a4:*/ 0x06, /* .....##. */
+ /*02a5:*/ 0xc6, /* ##...##. */
+ /*02a6:*/ 0xc6, /* ##...##. */
+ /*02a7:*/ 0xee, /* ###.###. */
+ /*02a8:*/ 0x7c, /* .#####.. */
+/* --- new character K (75) starting at offset 0x02a9 --- */
+ /*02a9:*/ 10, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02ae:*/ 0xc3,0x00, /* ##....##........ */
+ /*02b0:*/ 0xc6,0x00, /* ##...##......... */
+ /*02b2:*/ 0xcc,0x00, /* ##..##.......... */
+ /*02b4:*/ 0xd8,0x00, /* ##.##........... */
+ /*02b6:*/ 0xf0,0x00, /* ####............ */
+ /*02b8:*/ 0xf0,0x00, /* ####............ */
+ /*02ba:*/ 0xd8,0x00, /* ##.##........... */
+ /*02bc:*/ 0xcc,0x00, /* ##..##.......... */
+ /*02be:*/ 0xc6,0x00, /* ##...##......... */
+ /*02c0:*/ 0xc3,0x00, /* ##....##........ */
+ /*02c2:*/ 0xc1,0x80, /* ##.....##....... */
+/* --- new character L (76) starting at offset 0x02c4 --- */
+ /*02c4:*/ 8, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02c9:*/ 0xc0, /* ##...... */
+ /*02ca:*/ 0xc0, /* ##...... */
+ /*02cb:*/ 0xc0, /* ##...... */
+ /*02cc:*/ 0xc0, /* ##...... */
+ /*02cd:*/ 0xc0, /* ##...... */
+ /*02ce:*/ 0xc0, /* ##...... */
+ /*02cf:*/ 0xc0, /* ##...... */
+ /*02d0:*/ 0xc0, /* ##...... */
+ /*02d1:*/ 0xc0, /* ##...... */
+ /*02d2:*/ 0xc0, /* ##...... */
+ /*02d3:*/ 0xfe, /* #######. */
+/* --- new character M (77) starting at offset 0x02d4 --- */
+ /*02d4:*/ 13, 11, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02d9:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02db:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02dd:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*02df:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*02e1:*/ 0xf1,0xe0, /* ####...####..... */
+ /*02e3:*/ 0xd1,0x60, /* ##.#...#.##..... */
+ /*02e5:*/ 0xd1,0x60, /* ##.#...#.##..... */
+ /*02e7:*/ 0xdb,0x60, /* ##.##.##.##..... */
+ /*02e9:*/ 0xca,0x60, /* ##..#.#..##..... */
+ /*02eb:*/ 0xce,0x60, /* ##..###..##..... */
+ /*02ed:*/ 0xc4,0x60, /* ##...#...##..... */
+/* --- new character N (78) starting at offset 0x02ef --- */
+ /*02ef:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02f4:*/ 0xc1,0x80, /* ##.....##....... */
+ /*02f6:*/ 0xe1,0x80, /* ###....##....... */
+ /*02f8:*/ 0xe1,0x80, /* ###....##....... */
+ /*02fa:*/ 0xd1,0x80, /* ##.#...##....... */
+ /*02fc:*/ 0xd9,0x80, /* ##.##..##....... */
+ /*02fe:*/ 0xc9,0x80, /* ##..#..##....... */
+ /*0300:*/ 0xcd,0x80, /* ##..##.##....... */
+ /*0302:*/ 0xc5,0x80, /* ##...#.##....... */
+ /*0304:*/ 0xc3,0x80, /* ##....###....... */
+ /*0306:*/ 0xc3,0x80, /* ##....###....... */
+ /*0308:*/ 0xc1,0x80, /* ##.....##....... */
+/* --- new character O (79) starting at offset 0x030a --- */
+ /*030a:*/ 12, 10, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*030f:*/ 0x1e,0x00, /* ...####......... */
+ /*0311:*/ 0x73,0x80, /* .###..###....... */
+ /*0313:*/ 0x61,0x80, /* .##....##....... */
+ /*0315:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0317:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0319:*/ 0xc0,0xc0, /* ##......##...... */
+ /*031b:*/ 0xc0,0xc0, /* ##......##...... */
+ /*031d:*/ 0xc0,0xc0, /* ##......##...... */
+ /*031f:*/ 0x61,0x80, /* .##....##....... */
+ /*0321:*/ 0x73,0x80, /* .###..###....... */
+ /*0323:*/ 0x1e,0x00, /* ...####......... */
+/* --- new character P (80) starting at offset 0x0325 --- */
+ /*0325:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*032a:*/ 0xfe, /* #######. */
+ /*032b:*/ 0xc7, /* ##...### */
+ /*032c:*/ 0xc3, /* ##....## */
+ /*032d:*/ 0xc3, /* ##....## */
+ /*032e:*/ 0xc7, /* ##...### */
+ /*032f:*/ 0xfe, /* #######. */
+ /*0330:*/ 0xc0, /* ##...... */
+ /*0331:*/ 0xc0, /* ##...... */
+ /*0332:*/ 0xc0, /* ##...... */
+ /*0333:*/ 0xc0, /* ##...... */
+ /*0334:*/ 0xc0, /* ##...... */
+/* --- new character Q (81) starting at offset 0x0335 --- */
+ /*0335:*/ 12, 10, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*033a:*/ 0x1e,0x00, /* ...####......... */
+ /*033c:*/ 0x73,0x80, /* .###..###....... */
+ /*033e:*/ 0x61,0x80, /* .##....##....... */
+ /*0340:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0342:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0344:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0346:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0348:*/ 0xc6,0xc0, /* ##...##.##...... */
+ /*034a:*/ 0x63,0x80, /* .##...###....... */
+ /*034c:*/ 0x73,0x80, /* .###..###....... */
+ /*034e:*/ 0x1e,0xc0, /* ...####.##...... */
+/* --- new character R (82) starting at offset 0x0350 --- */
+ /*0350:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0355:*/ 0xfe,0x00, /* #######......... */
+ /*0357:*/ 0xc7,0x00, /* ##...###........ */
+ /*0359:*/ 0xc3,0x00, /* ##....##........ */
+ /*035b:*/ 0xc3,0x00, /* ##....##........ */
+ /*035d:*/ 0xc7,0x00, /* ##...###........ */
+ /*035f:*/ 0xfe,0x00, /* #######......... */
+ /*0361:*/ 0xc3,0x00, /* ##....##........ */
+ /*0363:*/ 0xc3,0x00, /* ##....##........ */
+ /*0365:*/ 0xc3,0x00, /* ##....##........ */
+ /*0367:*/ 0xc3,0x00, /* ##....##........ */
+ /*0369:*/ 0xc1,0x80, /* ##.....##....... */
+/* --- new character S (83) starting at offset 0x036b --- */
+ /*036b:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0370:*/ 0x7e, /* .######. */
+ /*0371:*/ 0xe7, /* ###..### */
+ /*0372:*/ 0xc3, /* ##....## */
+ /*0373:*/ 0xe0, /* ###..... */
+ /*0374:*/ 0x78, /* .####... */
+ /*0375:*/ 0x1e, /* ...####. */
+ /*0376:*/ 0x07, /* .....### */
+ /*0377:*/ 0x03, /* ......## */
+ /*0378:*/ 0xc3, /* ##....## */
+ /*0379:*/ 0xee, /* ###.###. */
+ /*037a:*/ 0x7c, /* .#####.. */
+/* --- new character T (84) starting at offset 0x037b --- */
+ /*037b:*/ 8, 8, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0380:*/ 0xff, /* ######## */
+ /*0381:*/ 0x18, /* ...##... */
+ /*0382:*/ 0x18, /* ...##... */
+ /*0383:*/ 0x18, /* ...##... */
+ /*0384:*/ 0x18, /* ...##... */
+ /*0385:*/ 0x18, /* ...##... */
+ /*0386:*/ 0x18, /* ...##... */
+ /*0387:*/ 0x18, /* ...##... */
+ /*0388:*/ 0x18, /* ...##... */
+ /*0389:*/ 0x18, /* ...##... */
+ /*038a:*/ 0x18, /* ...##... */
+/* --- new character U (85) starting at offset 0x038b --- */
+ /*038b:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0390:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0392:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0394:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0396:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0398:*/ 0xc1,0x80, /* ##.....##....... */
+ /*039a:*/ 0xc1,0x80, /* ##.....##....... */
+ /*039c:*/ 0xc1,0x80, /* ##.....##....... */
+ /*039e:*/ 0xc1,0x80, /* ##.....##....... */
+ /*03a0:*/ 0xc1,0x80, /* ##.....##....... */
+ /*03a2:*/ 0x63,0x00, /* .##...##........ */
+ /*03a4:*/ 0x3e,0x00, /* ..#####......... */
+/* --- new character V (86) starting at offset 0x03a6 --- */
+ /*03a6:*/ 10, 10, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03ab:*/ 0xc0,0xc0, /* ##......##...... */
+ /*03ad:*/ 0xc0,0xc0, /* ##......##...... */
+ /*03af:*/ 0x61,0x80, /* .##....##....... */
+ /*03b1:*/ 0x61,0x80, /* .##....##....... */
+ /*03b3:*/ 0x73,0x80, /* .###..###....... */
+ /*03b5:*/ 0x33,0x00, /* ..##..##........ */
+ /*03b7:*/ 0x33,0x00, /* ..##..##........ */
+ /*03b9:*/ 0x1e,0x00, /* ...####......... */
+ /*03bb:*/ 0x1e,0x00, /* ...####......... */
+ /*03bd:*/ 0x0c,0x00, /* ....##.......... */
+ /*03bf:*/ 0x0c,0x00, /* ....##.......... */
+/* --- new character W (87) starting at offset 0x03c1 --- */
+ /*03c1:*/ 14, 14, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03c6:*/ 0xc3,0x0c, /* ##....##....##.. */
+ /*03c8:*/ 0xc3,0x0c, /* ##....##....##.. */
+ /*03ca:*/ 0xc3,0x0c, /* ##....##....##.. */
+ /*03cc:*/ 0x67,0x98, /* .##..####..##... */
+ /*03ce:*/ 0x64,0x98, /* .##..#..#..##... */
+ /*03d0:*/ 0x64,0x98, /* .##..#..#..##... */
+ /*03d2:*/ 0x6c,0xd8, /* .##.##..##.##... */
+ /*03d4:*/ 0x2c,0xd0, /* ..#.##..##.#.... */
+ /*03d6:*/ 0x38,0x70, /* ..###....###.... */
+ /*03d8:*/ 0x18,0x60, /* ...##....##..... */
+ /*03da:*/ 0x18,0x60, /* ...##....##..... */
+/* --- new character X (88) starting at offset 0x03dc --- */
+ /*03dc:*/ 9, 9, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03e1:*/ 0xc1,0x80, /* ##.....##....... */
+ /*03e3:*/ 0xc1,0x80, /* ##.....##....... */
+ /*03e5:*/ 0x63,0x00, /* .##...##........ */
+ /*03e7:*/ 0x36,0x00, /* ..##.##......... */
+ /*03e9:*/ 0x1c,0x00, /* ...###.......... */
+ /*03eb:*/ 0x1c,0x00, /* ...###.......... */
+ /*03ed:*/ 0x36,0x00, /* ..##.##......... */
+ /*03ef:*/ 0x63,0x00, /* .##...##........ */
+ /*03f1:*/ 0x63,0x00, /* .##...##........ */
+ /*03f3:*/ 0xc1,0x80, /* ##.....##....... */
+ /*03f5:*/ 0xc1,0x80, /* ##.....##....... */
+/* --- new character Y (89) starting at offset 0x03f7 --- */
+ /*03f7:*/ 10, 10, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03fc:*/ 0xc0,0xc0, /* ##......##...... */
+ /*03fe:*/ 0x61,0x80, /* .##....##....... */
+ /*0400:*/ 0x61,0x80, /* .##....##....... */
+ /*0402:*/ 0x33,0x00, /* ..##..##........ */
+ /*0404:*/ 0x33,0x00, /* ..##..##........ */
+ /*0406:*/ 0x1e,0x00, /* ...####......... */
+ /*0408:*/ 0x1e,0x00, /* ...####......... */
+ /*040a:*/ 0x0c,0x00, /* ....##.......... */
+ /*040c:*/ 0x0c,0x00, /* ....##.......... */
+ /*040e:*/ 0x0c,0x00, /* ....##.......... */
+ /*0410:*/ 0x0c,0x00, /* ....##.......... */
+/* --- new character Z (90) starting at offset 0x0412 --- */
+ /*0412:*/ 9, 8, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0417:*/ 0xff, /* ######## */
+ /*0418:*/ 0x03, /* ......## */
+ /*0419:*/ 0x06, /* .....##. */
+ /*041a:*/ 0x0c, /* ....##.. */
+ /*041b:*/ 0x1c, /* ...###.. */
+ /*041c:*/ 0x18, /* ...##... */
+ /*041d:*/ 0x30, /* ..##.... */
+ /*041e:*/ 0x70, /* .###.... */
+ /*041f:*/ 0x60, /* .##..... */
+ /*0420:*/ 0xc0, /* ##...... */
+ /*0421:*/ 0xff, /* ######## */
+/* --- new character bracketleft (91) starting at offset 0x0422 --- */
+ /*0422:*/ 5, 4, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0427:*/ 0xf0, /* ####.... */
+ /*0428:*/ 0xc0, /* ##...... */
+ /*0429:*/ 0xc0, /* ##...... */
+ /*042a:*/ 0xc0, /* ##...... */
+ /*042b:*/ 0xc0, /* ##...... */
+ /*042c:*/ 0xc0, /* ##...... */
+ /*042d:*/ 0xc0, /* ##...... */
+ /*042e:*/ 0xc0, /* ##...... */
+ /*042f:*/ 0xc0, /* ##...... */
+ /*0430:*/ 0xc0, /* ##...... */
+ /*0431:*/ 0xc0, /* ##...... */
+ /*0432:*/ 0xc0, /* ##...... */
+ /*0433:*/ 0xc0, /* ##...... */
+ /*0434:*/ 0xf0, /* ####.... */
+/* --- new character backslash (92) starting at offset 0x0435 --- */
+ /*0435:*/ 4, 4, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*043a:*/ 0xc0, /* ##...... */
+ /*043b:*/ 0xc0, /* ##...... */
+ /*043c:*/ 0xc0, /* ##...... */
+ /*043d:*/ 0x40, /* .#...... */
+ /*043e:*/ 0x60, /* .##..... */
+ /*043f:*/ 0x60, /* .##..... */
+ /*0440:*/ 0x60, /* .##..... */
+ /*0441:*/ 0x20, /* ..#..... */
+ /*0442:*/ 0x30, /* ..##.... */
+ /*0443:*/ 0x30, /* ..##.... */
+ /*0444:*/ 0x30, /* ..##.... */
+/* --- new character bracketright (93) starting at offset 0x0445 --- */
+ /*0445:*/ 5, 4, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*044a:*/ 0xf0, /* ####.... */
+ /*044b:*/ 0x30, /* ..##.... */
+ /*044c:*/ 0x30, /* ..##.... */
+ /*044d:*/ 0x30, /* ..##.... */
+ /*044e:*/ 0x30, /* ..##.... */
+ /*044f:*/ 0x30, /* ..##.... */
+ /*0450:*/ 0x30, /* ..##.... */
+ /*0451:*/ 0x30, /* ..##.... */
+ /*0452:*/ 0x30, /* ..##.... */
+ /*0453:*/ 0x30, /* ..##.... */
+ /*0454:*/ 0x30, /* ..##.... */
+ /*0455:*/ 0x30, /* ..##.... */
+ /*0456:*/ 0x30, /* ..##.... */
+ /*0457:*/ 0xf0, /* ####.... */
+/* --- new character asciicircum (94) starting at offset 0x0458 --- */
+ /*0458:*/ 8, 6, 4, 1, 7, /* width and bbox (w,h,x,y) */
+ /*045d:*/ 0x30, /* ..##.... */
+ /*045e:*/ 0x78, /* .####... */
+ /*045f:*/ 0xcc, /* ##..##.. */
+ /*0460:*/ 0x84, /* #....#.. */
+/* --- new character underscore (95) starting at offset 0x0461 --- */
+ /*0461:*/ 8, 8, 1, 0, -3, /* width and bbox (w,h,x,y) */
+ /*0466:*/ 0xff, /* ######## */
+/* --- new character grave (96) starting at offset 0x0467 --- */
+ /*0467:*/ 5, 3, 2, 1, 9, /* width and bbox (w,h,x,y) */
+ /*046c:*/ 0xc0, /* ##...... */
+ /*046d:*/ 0x60, /* .##..... */
+/* --- new character a (97) starting at offset 0x046e --- */
+ /*046e:*/ 8, 7, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0473:*/ 0x78, /* .####... */
+ /*0474:*/ 0xcc, /* ##..##.. */
+ /*0475:*/ 0x0c, /* ....##.. */
+ /*0476:*/ 0x7c, /* .#####.. */
+ /*0477:*/ 0xcc, /* ##..##.. */
+ /*0478:*/ 0xcc, /* ##..##.. */
+ /*0479:*/ 0xfc, /* ######.. */
+ /*047a:*/ 0x76, /* .###.##. */
+/* --- new character b (98) starting at offset 0x047b --- */
+ /*047b:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0480:*/ 0xc0, /* ##...... */
+ /*0481:*/ 0xc0, /* ##...... */
+ /*0482:*/ 0xc0, /* ##...... */
+ /*0483:*/ 0xf8, /* #####... */
+ /*0484:*/ 0xec, /* ###.##.. */
+ /*0485:*/ 0xc6, /* ##...##. */
+ /*0486:*/ 0xc6, /* ##...##. */
+ /*0487:*/ 0xc6, /* ##...##. */
+ /*0488:*/ 0xc6, /* ##...##. */
+ /*0489:*/ 0xec, /* ###.##.. */
+ /*048a:*/ 0xd8, /* ##.##... */
+/* --- new character c (99) starting at offset 0x048b --- */
+ /*048b:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0490:*/ 0x38, /* ..###... */
+ /*0491:*/ 0x7c, /* .#####.. */
+ /*0492:*/ 0xc4, /* ##...#.. */
+ /*0493:*/ 0xc0, /* ##...... */
+ /*0494:*/ 0xc0, /* ##...... */
+ /*0495:*/ 0xc4, /* ##...#.. */
+ /*0496:*/ 0x7c, /* .#####.. */
+ /*0497:*/ 0x38, /* ..###... */
+/* --- new character d (100) starting at offset 0x0498 --- */
+ /*0498:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*049d:*/ 0x06, /* .....##. */
+ /*049e:*/ 0x06, /* .....##. */
+ /*049f:*/ 0x06, /* .....##. */
+ /*04a0:*/ 0x3e, /* ..#####. */
+ /*04a1:*/ 0x6e, /* .##.###. */
+ /*04a2:*/ 0xc6, /* ##...##. */
+ /*04a3:*/ 0xc6, /* ##...##. */
+ /*04a4:*/ 0xc6, /* ##...##. */
+ /*04a5:*/ 0xc6, /* ##...##. */
+ /*04a6:*/ 0x6e, /* .##.###. */
+ /*04a7:*/ 0x36, /* ..##.##. */
+/* --- new character e (101) starting at offset 0x04a8 --- */
+ /*04a8:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04ad:*/ 0x78, /* .####... */
+ /*04ae:*/ 0xcc, /* ##..##.. */
+ /*04af:*/ 0xcc, /* ##..##.. */
+ /*04b0:*/ 0xfc, /* ######.. */
+ /*04b1:*/ 0xc0, /* ##...... */
+ /*04b2:*/ 0xc0, /* ##...... */
+ /*04b3:*/ 0xec, /* ###.##.. */
+ /*04b4:*/ 0x78, /* .####... */
+/* --- new character f (102) starting at offset 0x04b5 --- */
+ /*04b5:*/ 4, 5, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*04ba:*/ 0x38, /* ..###... */
+ /*04bb:*/ 0x60, /* .##..... */
+ /*04bc:*/ 0x60, /* .##..... */
+ /*04bd:*/ 0xf0, /* ####.... */
+ /*04be:*/ 0x60, /* .##..... */
+ /*04bf:*/ 0x60, /* .##..... */
+ /*04c0:*/ 0x60, /* .##..... */
+ /*04c1:*/ 0x60, /* .##..... */
+ /*04c2:*/ 0x60, /* .##..... */
+ /*04c3:*/ 0x60, /* .##..... */
+ /*04c4:*/ 0x60, /* .##..... */
+/* --- new character g (103) starting at offset 0x04c5 --- */
+ /*04c5:*/ 9, 7, 11, 1, -3, /* width and bbox (w,h,x,y) */
+ /*04ca:*/ 0x3a, /* ..###.#. */
+ /*04cb:*/ 0x6e, /* .##.###. */
+ /*04cc:*/ 0xc6, /* ##...##. */
+ /*04cd:*/ 0xc6, /* ##...##. */
+ /*04ce:*/ 0xc6, /* ##...##. */
+ /*04cf:*/ 0xc6, /* ##...##. */
+ /*04d0:*/ 0x6e, /* .##.###. */
+ /*04d1:*/ 0x3e, /* ..#####. */
+ /*04d2:*/ 0x06, /* .....##. */
+ /*04d3:*/ 0xce, /* ##..###. */
+ /*04d4:*/ 0x7c, /* .#####.. */
+/* --- new character h (104) starting at offset 0x04d5 --- */
+ /*04d5:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04da:*/ 0xc0, /* ##...... */
+ /*04db:*/ 0xc0, /* ##...... */
+ /*04dc:*/ 0xc0, /* ##...... */
+ /*04dd:*/ 0xdc, /* ##.###.. */
+ /*04de:*/ 0xee, /* ###.###. */
+ /*04df:*/ 0xc6, /* ##...##. */
+ /*04e0:*/ 0xc6, /* ##...##. */
+ /*04e1:*/ 0xc6, /* ##...##. */
+ /*04e2:*/ 0xc6, /* ##...##. */
+ /*04e3:*/ 0xc6, /* ##...##. */
+ /*04e4:*/ 0xc6, /* ##...##. */
+/* --- new character i (105) starting at offset 0x04e5 --- */
+ /*04e5:*/ 4, 2, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04ea:*/ 0xc0, /* ##...... */
+ /*04eb:*/ 0xc0, /* ##...... */
+ /*04ec:*/ 0x00, /* ........ */
+ /*04ed:*/ 0xc0, /* ##...... */
+ /*04ee:*/ 0xc0, /* ##...... */
+ /*04ef:*/ 0xc0, /* ##...... */
+ /*04f0:*/ 0xc0, /* ##...... */
+ /*04f1:*/ 0xc0, /* ##...... */
+ /*04f2:*/ 0xc0, /* ##...... */
+ /*04f3:*/ 0xc0, /* ##...... */
+ /*04f4:*/ 0xc0, /* ##...... */
+/* --- new character j (106) starting at offset 0x04f5 --- */
+ /*04f5:*/ 4, 3, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*04fa:*/ 0x60, /* .##..... */
+ /*04fb:*/ 0x60, /* .##..... */
+ /*04fc:*/ 0x00, /* ........ */
+ /*04fd:*/ 0x60, /* .##..... */
+ /*04fe:*/ 0x60, /* .##..... */
+ /*04ff:*/ 0x60, /* .##..... */
+ /*0500:*/ 0x60, /* .##..... */
+ /*0501:*/ 0x60, /* .##..... */
+ /*0502:*/ 0x60, /* .##..... */
+ /*0503:*/ 0x60, /* .##..... */
+ /*0504:*/ 0x60, /* .##..... */
+ /*0505:*/ 0x60, /* .##..... */
+ /*0506:*/ 0xe0, /* ###..... */
+ /*0507:*/ 0xc0, /* ##...... */
+/* --- new character k (107) starting at offset 0x0508 --- */
+ /*0508:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*050d:*/ 0xc0, /* ##...... */
+ /*050e:*/ 0xc0, /* ##...... */
+ /*050f:*/ 0xc0, /* ##...... */
+ /*0510:*/ 0xcc, /* ##..##.. */
+ /*0511:*/ 0xd8, /* ##.##... */
+ /*0512:*/ 0xf0, /* ####.... */
+ /*0513:*/ 0xf0, /* ####.... */
+ /*0514:*/ 0xd8, /* ##.##... */
+ /*0515:*/ 0xd8, /* ##.##... */
+ /*0516:*/ 0xcc, /* ##..##.. */
+ /*0517:*/ 0xcc, /* ##..##.. */
+/* --- new character l (108) starting at offset 0x0518 --- */
+ /*0518:*/ 4, 2, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*051d:*/ 0xc0, /* ##...... */
+ /*051e:*/ 0xc0, /* ##...... */
+ /*051f:*/ 0xc0, /* ##...... */
+ /*0520:*/ 0xc0, /* ##...... */
+ /*0521:*/ 0xc0, /* ##...... */
+ /*0522:*/ 0xc0, /* ##...... */
+ /*0523:*/ 0xc0, /* ##...... */
+ /*0524:*/ 0xc0, /* ##...... */
+ /*0525:*/ 0xc0, /* ##...... */
+ /*0526:*/ 0xc0, /* ##...... */
+ /*0527:*/ 0xc0, /* ##...... */
+/* --- new character m (109) starting at offset 0x0528 --- */
+ /*0528:*/ 12, 10, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*052d:*/ 0xdb,0x80, /* ##.##.###....... */
+ /*052f:*/ 0xee,0xc0, /* ###.###.##...... */
+ /*0531:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*0533:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*0535:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*0537:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*0539:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*053b:*/ 0xcc,0xc0, /* ##..##..##...... */
+/* --- new character n (110) starting at offset 0x053d --- */
+ /*053d:*/ 9, 7, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0542:*/ 0xdc, /* ##.###.. */
+ /*0543:*/ 0xee, /* ###.###. */
+ /*0544:*/ 0xc6, /* ##...##. */
+ /*0545:*/ 0xc6, /* ##...##. */
+ /*0546:*/ 0xc6, /* ##...##. */
+ /*0547:*/ 0xc6, /* ##...##. */
+ /*0548:*/ 0xc6, /* ##...##. */
+ /*0549:*/ 0xc6, /* ##...##. */
+/* --- new character o (111) starting at offset 0x054a --- */
+ /*054a:*/ 9, 7, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*054f:*/ 0x38, /* ..###... */
+ /*0550:*/ 0x6c, /* .##.##.. */
+ /*0551:*/ 0xc6, /* ##...##. */
+ /*0552:*/ 0xc6, /* ##...##. */
+ /*0553:*/ 0xc6, /* ##...##. */
+ /*0554:*/ 0xc6, /* ##...##. */
+ /*0555:*/ 0x6c, /* .##.##.. */
+ /*0556:*/ 0x38, /* ..###... */
+/* --- new character p (112) starting at offset 0x0557 --- */
+ /*0557:*/ 9, 7, 11, 1, -3, /* width and bbox (w,h,x,y) */
+ /*055c:*/ 0xd8, /* ##.##... */
+ /*055d:*/ 0xec, /* ###.##.. */
+ /*055e:*/ 0xc6, /* ##...##. */
+ /*055f:*/ 0xc6, /* ##...##. */
+ /*0560:*/ 0xc6, /* ##...##. */
+ /*0561:*/ 0xc6, /* ##...##. */
+ /*0562:*/ 0xec, /* ###.##.. */
+ /*0563:*/ 0xf8, /* #####... */
+ /*0564:*/ 0xc0, /* ##...... */
+ /*0565:*/ 0xc0, /* ##...... */
+ /*0566:*/ 0xc0, /* ##...... */
+/* --- new character q (113) starting at offset 0x0567 --- */
+ /*0567:*/ 9, 7, 11, 1, -3, /* width and bbox (w,h,x,y) */
+ /*056c:*/ 0x36, /* ..##.##. */
+ /*056d:*/ 0x6e, /* .##.###. */
+ /*056e:*/ 0xc6, /* ##...##. */
+ /*056f:*/ 0xc6, /* ##...##. */
+ /*0570:*/ 0xc6, /* ##...##. */
+ /*0571:*/ 0xc6, /* ##...##. */
+ /*0572:*/ 0x6e, /* .##.###. */
+ /*0573:*/ 0x3e, /* ..#####. */
+ /*0574:*/ 0x06, /* .....##. */
+ /*0575:*/ 0x06, /* .....##. */
+ /*0576:*/ 0x06, /* .....##. */
+/* --- new character r (114) starting at offset 0x0577 --- */
+ /*0577:*/ 6, 5, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*057c:*/ 0xd8, /* ##.##... */
+ /*057d:*/ 0xf8, /* #####... */
+ /*057e:*/ 0xc0, /* ##...... */
+ /*057f:*/ 0xc0, /* ##...... */
+ /*0580:*/ 0xc0, /* ##...... */
+ /*0581:*/ 0xc0, /* ##...... */
+ /*0582:*/ 0xc0, /* ##...... */
+ /*0583:*/ 0xc0, /* ##...... */
+/* --- new character s (115) starting at offset 0x0584 --- */
+ /*0584:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0589:*/ 0x78, /* .####... */
+ /*058a:*/ 0xec, /* ###.##.. */
+ /*058b:*/ 0xc0, /* ##...... */
+ /*058c:*/ 0x78, /* .####... */
+ /*058d:*/ 0x1c, /* ...###.. */
+ /*058e:*/ 0x0c, /* ....##.. */
+ /*058f:*/ 0xec, /* ###.##.. */
+ /*0590:*/ 0x78, /* .####... */
+/* --- new character t (116) starting at offset 0x0591 --- */
+ /*0591:*/ 5, 5, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0596:*/ 0x60, /* .##..... */
+ /*0597:*/ 0x60, /* .##..... */
+ /*0598:*/ 0xf8, /* #####... */
+ /*0599:*/ 0x60, /* .##..... */
+ /*059a:*/ 0x60, /* .##..... */
+ /*059b:*/ 0x60, /* .##..... */
+ /*059c:*/ 0x60, /* .##..... */
+ /*059d:*/ 0x60, /* .##..... */
+ /*059e:*/ 0x68, /* .##.#... */
+ /*059f:*/ 0x30, /* ..##.... */
+/* --- new character u (117) starting at offset 0x05a0 --- */
+ /*05a0:*/ 9, 7, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*05a5:*/ 0xc6, /* ##...##. */
+ /*05a6:*/ 0xc6, /* ##...##. */
+ /*05a7:*/ 0xc6, /* ##...##. */
+ /*05a8:*/ 0xc6, /* ##...##. */
+ /*05a9:*/ 0xc6, /* ##...##. */
+ /*05aa:*/ 0xc6, /* ##...##. */
+ /*05ab:*/ 0xee, /* ###.###. */
+ /*05ac:*/ 0x76, /* .###.##. */
+/* --- new character v (118) starting at offset 0x05ad --- */
+ /*05ad:*/ 8, 8, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*05b2:*/ 0xc3, /* ##....## */
+ /*05b3:*/ 0xc3, /* ##....## */
+ /*05b4:*/ 0x66, /* .##..##. */
+ /*05b5:*/ 0x66, /* .##..##. */
+ /*05b6:*/ 0x24, /* ..#..#.. */
+ /*05b7:*/ 0x3c, /* ..####.. */
+ /*05b8:*/ 0x18, /* ...##... */
+ /*05b9:*/ 0x18, /* ...##... */
+/* --- new character w (119) starting at offset 0x05ba --- */
+ /*05ba:*/ 10, 10, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*05bf:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*05c1:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*05c3:*/ 0xcc,0xc0, /* ##..##..##...... */
+ /*05c5:*/ 0x6d,0x80, /* .##.##.##....... */
+ /*05c7:*/ 0x6d,0x80, /* .##.##.##....... */
+ /*05c9:*/ 0x33,0x00, /* ..##..##........ */
+ /*05cb:*/ 0x33,0x00, /* ..##..##........ */
+ /*05cd:*/ 0x33,0x00, /* ..##..##........ */
+/* --- new character x (120) starting at offset 0x05cf --- */
+ /*05cf:*/ 7, 7, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*05d4:*/ 0xc6, /* ##...##. */
+ /*05d5:*/ 0xc6, /* ##...##. */
+ /*05d6:*/ 0x6c, /* .##.##.. */
+ /*05d7:*/ 0x38, /* ..###... */
+ /*05d8:*/ 0x38, /* ..###... */
+ /*05d9:*/ 0x6c, /* .##.##.. */
+ /*05da:*/ 0xc6, /* ##...##. */
+ /*05db:*/ 0xc6, /* ##...##. */
+/* --- new character y (121) starting at offset 0x05dc --- */
+ /*05dc:*/ 8, 8, 11, 0, -3, /* width and bbox (w,h,x,y) */
+ /*05e1:*/ 0xc3, /* ##....## */
+ /*05e2:*/ 0xc3, /* ##....## */
+ /*05e3:*/ 0x66, /* .##..##. */
+ /*05e4:*/ 0x66, /* .##..##. */
+ /*05e5:*/ 0x24, /* ..#..#.. */
+ /*05e6:*/ 0x3c, /* ..####.. */
+ /*05e7:*/ 0x18, /* ...##... */
+ /*05e8:*/ 0x18, /* ...##... */
+ /*05e9:*/ 0x18, /* ...##... */
+ /*05ea:*/ 0x30, /* ..##.... */
+ /*05eb:*/ 0x70, /* .###.... */
+/* --- new character z (122) starting at offset 0x05ec --- */
+ /*05ec:*/ 6, 6, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*05f1:*/ 0xfc, /* ######.. */
+ /*05f2:*/ 0x0c, /* ....##.. */
+ /*05f3:*/ 0x18, /* ...##... */
+ /*05f4:*/ 0x30, /* ..##.... */
+ /*05f5:*/ 0x30, /* ..##.... */
+ /*05f6:*/ 0x60, /* .##..... */
+ /*05f7:*/ 0xc0, /* ##...... */
+ /*05f8:*/ 0xfc, /* ######.. */
+/* --- new character braceleft (123) starting at offset 0x05f9 --- */
+ /*05f9:*/ 6, 5, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*05fe:*/ 0x18, /* ...##... */
+ /*05ff:*/ 0x30, /* ..##.... */
+ /*0600:*/ 0x30, /* ..##.... */
+ /*0601:*/ 0x30, /* ..##.... */
+ /*0602:*/ 0x30, /* ..##.... */
+ /*0603:*/ 0x60, /* .##..... */
+ /*0604:*/ 0xc0, /* ##...... */
+ /*0605:*/ 0x60, /* .##..... */
+ /*0606:*/ 0x30, /* ..##.... */
+ /*0607:*/ 0x30, /* ..##.... */
+ /*0608:*/ 0x30, /* ..##.... */
+ /*0609:*/ 0x30, /* ..##.... */
+ /*060a:*/ 0x30, /* ..##.... */
+ /*060b:*/ 0x18, /* ...##... */
+/* --- new character bar (124) starting at offset 0x060c --- */
+ /*060c:*/ 4, 2, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0611:*/ 0xc0, /* ##...... */
+ /*0612:*/ 0xc0, /* ##...... */
+ /*0613:*/ 0xc0, /* ##...... */
+ /*0614:*/ 0xc0, /* ##...... */
+ /*0615:*/ 0xc0, /* ##...... */
+ /*0616:*/ 0xc0, /* ##...... */
+ /*0617:*/ 0xc0, /* ##...... */
+ /*0618:*/ 0xc0, /* ##...... */
+ /*0619:*/ 0xc0, /* ##...... */
+ /*061a:*/ 0xc0, /* ##...... */
+ /*061b:*/ 0xc0, /* ##...... */
+ /*061c:*/ 0xc0, /* ##...... */
+ /*061d:*/ 0xc0, /* ##...... */
+ /*061e:*/ 0xc0, /* ##...... */
+/* --- new character braceright (125) starting at offset 0x061f --- */
+ /*061f:*/ 6, 5, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0624:*/ 0xc0, /* ##...... */
+ /*0625:*/ 0x60, /* .##..... */
+ /*0626:*/ 0x60, /* .##..... */
+ /*0627:*/ 0x60, /* .##..... */
+ /*0628:*/ 0x60, /* .##..... */
+ /*0629:*/ 0x30, /* ..##.... */
+ /*062a:*/ 0x18, /* ...##... */
+ /*062b:*/ 0x30, /* ..##.... */
+ /*062c:*/ 0x60, /* .##..... */
+ /*062d:*/ 0x60, /* .##..... */
+ /*062e:*/ 0x60, /* .##..... */
+ /*062f:*/ 0x60, /* .##..... */
+ /*0630:*/ 0x60, /* .##..... */
+ /*0631:*/ 0xc0, /* ##...... */
+/* --- new character asciitilde (126) starting at offset 0x0632 --- */
+ /*0632:*/ 9, 7, 3, 1, 3, /* width and bbox (w,h,x,y) */
+ /*0637:*/ 0x72, /* .###..#. */
+ /*0638:*/ 0xde, /* ##.####. */
+ /*0639:*/ 0x8c, /* #...##.. */
+};
+static const uint16_t font_helvB14_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x0016 /* quotedbl */,
+ 0x001e /* numbersign */,
+ 0x0037 /* dollar */,
+ 0x0049 /* percent */,
+ 0x0062 /* ampersand */,
+ 0x007b /* quotesingle */,
+ 0x0083 /* parenleft */,
+ 0x0096 /* parenright */,
+ 0x00a9 /* asterisk */,
+ 0x00b2 /* plus */,
+ 0x00be /* comma */,
+ 0x00c6 /* hyphen */,
+ 0x00cc /* period */,
+ 0x00d3 /* slash */,
+ 0x00e3 /* zero */,
+ 0x00f2 /* one */,
+ 0x0101 /* two */,
+ 0x0110 /* three */,
+ 0x011f /* four */,
+ 0x012e /* five */,
+ 0x013d /* six */,
+ 0x014c /* seven */,
+ 0x015b /* eight */,
+ 0x016a /* nine */,
+ 0x0179 /* colon */,
+ 0x0186 /* semicolon */,
+ 0x0194 /* less */,
+ 0x019e /* equal */,
+ 0x01a6 /* greater */,
+ 0x01b0 /* question */,
+ 0x01c0 /* at */,
+ 0x01dd /* A */,
+ 0x01f8 /* B */,
+ 0x0208 /* C */,
+ 0x0223 /* D */,
+ 0x023e /* E */,
+ 0x024e /* F */,
+ 0x025e /* G */,
+ 0x0279 /* H */,
+ 0x0289 /* I */,
+ 0x0299 /* J */,
+ 0x02a9 /* K */,
+ 0x02c4 /* L */,
+ 0x02d4 /* M */,
+ 0x02ef /* N */,
+ 0x030a /* O */,
+ 0x0325 /* P */,
+ 0x0335 /* Q */,
+ 0x0350 /* R */,
+ 0x036b /* S */,
+ 0x037b /* T */,
+ 0x038b /* U */,
+ 0x03a6 /* V */,
+ 0x03c1 /* W */,
+ 0x03dc /* X */,
+ 0x03f7 /* Y */,
+ 0x0412 /* Z */,
+ 0x0422 /* bracketleft */,
+ 0x0435 /* backslash */,
+ 0x0445 /* bracketright */,
+ 0x0458 /* asciicircum */,
+ 0x0461 /* underscore */,
+ 0x0467 /* grave */,
+ 0x046e /* a */,
+ 0x047b /* b */,
+ 0x048b /* c */,
+ 0x0498 /* d */,
+ 0x04a8 /* e */,
+ 0x04b5 /* f */,
+ 0x04c5 /* g */,
+ 0x04d5 /* h */,
+ 0x04e5 /* i */,
+ 0x04f5 /* j */,
+ 0x0508 /* k */,
+ 0x0518 /* l */,
+ 0x0528 /* m */,
+ 0x053d /* n */,
+ 0x054a /* o */,
+ 0x0557 /* p */,
+ 0x0567 /* q */,
+ 0x0577 /* r */,
+ 0x0584 /* s */,
+ 0x0591 /* t */,
+ 0x05a0 /* u */,
+ 0x05ad /* v */,
+ 0x05ba /* w */,
+ 0x05cf /* x */,
+ 0x05dc /* y */,
+ 0x05ec /* z */,
+ 0x05f9 /* braceleft */,
+ 0x060c /* bar */,
+ 0x061f /* braceright */,
+ 0x0632 /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_helvB14 = {
+ .height = 16,
+ .ascent = 13,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_helvB14_data,
+ .charoffs = font_helvB14_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/helvB24.c b/Src/osmolib/src/target/firmware/fb/helvB24.c
new file mode 100644
index 0000000..509b9db
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/helvB24.c
@@ -0,0 +1,1871 @@
+#include <fb/font.h>
+static const uint8_t font_helvB24_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 6, 1, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 7, 3, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0xe0, /* ###..... */
+ /*000c:*/ 0xe0, /* ###..... */
+ /*000d:*/ 0xe0, /* ###..... */
+ /*000e:*/ 0xe0, /* ###..... */
+ /*000f:*/ 0xe0, /* ###..... */
+ /*0010:*/ 0xe0, /* ###..... */
+ /*0011:*/ 0xe0, /* ###..... */
+ /*0012:*/ 0xe0, /* ###..... */
+ /*0013:*/ 0xe0, /* ###..... */
+ /*0014:*/ 0xe0, /* ###..... */
+ /*0015:*/ 0xe0, /* ###..... */
+ /*0016:*/ 0xe0, /* ###..... */
+ /*0017:*/ 0xe0, /* ###..... */
+ /*0018:*/ 0xe0, /* ###..... */
+ /*0019:*/ 0x00, /* ........ */
+ /*001a:*/ 0x00, /* ........ */
+ /*001b:*/ 0xe0, /* ###..... */
+ /*001c:*/ 0xe0, /* ###..... */
+ /*001d:*/ 0xe0, /* ###..... */
+/* --- new character quotedbl (34) starting at offset 0x001e --- */
+ /*001e:*/ 9, 5, 6, 2, 13, /* width and bbox (w,h,x,y) */
+ /*0023:*/ 0xd8, /* ##.##... */
+ /*0024:*/ 0xd8, /* ##.##... */
+ /*0025:*/ 0xd8, /* ##.##... */
+ /*0026:*/ 0xd8, /* ##.##... */
+ /*0027:*/ 0xd8, /* ##.##... */
+ /*0028:*/ 0x90, /* #..#.... */
+/* --- new character numbersign (35) starting at offset 0x0029 --- */
+ /*0029:*/ 14, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*002e:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0030:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0032:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0034:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0036:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0038:*/ 0x7f,0xf0, /* .###########.... */
+ /*003a:*/ 0x7f,0xf0, /* .###########.... */
+ /*003c:*/ 0x19,0x80, /* ...##..##....... */
+ /*003e:*/ 0x19,0x80, /* ...##..##....... */
+ /*0040:*/ 0x19,0x80, /* ...##..##....... */
+ /*0042:*/ 0x19,0x80, /* ...##..##....... */
+ /*0044:*/ 0xff,0xe0, /* ###########..... */
+ /*0046:*/ 0xff,0xe0, /* ###########..... */
+ /*0048:*/ 0x33,0x00, /* ..##..##........ */
+ /*004a:*/ 0x33,0x00, /* ..##..##........ */
+ /*004c:*/ 0x33,0x00, /* ..##..##........ */
+ /*004e:*/ 0x33,0x00, /* ..##..##........ */
+ /*0050:*/ 0x33,0x00, /* ..##..##........ */
+/* --- new character dollar (36) starting at offset 0x0052 --- */
+ /*0052:*/ 13, 12, 21, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0057:*/ 0x06,0x00, /* .....##......... */
+ /*0059:*/ 0x3f,0x80, /* ..#######....... */
+ /*005b:*/ 0x7f,0xc0, /* .#########...... */
+ /*005d:*/ 0xf6,0xe0, /* ####.##.###..... */
+ /*005f:*/ 0xe6,0xe0, /* ###..##.###..... */
+ /*0061:*/ 0xe6,0xe0, /* ###..##.###..... */
+ /*0063:*/ 0xf6,0x00, /* ####.##......... */
+ /*0065:*/ 0x7e,0x00, /* .######......... */
+ /*0067:*/ 0x3e,0x00, /* ..#####......... */
+ /*0069:*/ 0x0f,0x00, /* ....####........ */
+ /*006b:*/ 0x07,0xc0, /* .....#####...... */
+ /*006d:*/ 0x07,0xe0, /* .....######..... */
+ /*006f:*/ 0x06,0xf0, /* .....##.####.... */
+ /*0071:*/ 0xe6,0x70, /* ###..##..###.... */
+ /*0073:*/ 0xe6,0x70, /* ###..##..###.... */
+ /*0075:*/ 0xe6,0x70, /* ###..##..###.... */
+ /*0077:*/ 0xf6,0xf0, /* ####.##.####.... */
+ /*0079:*/ 0x7f,0xe0, /* .##########..... */
+ /*007b:*/ 0x1f,0xc0, /* ...#######...... */
+ /*007d:*/ 0x06,0x00, /* .....##......... */
+ /*007f:*/ 0x06,0x00, /* .....##......... */
+/* --- new character percent (37) starting at offset 0x0081 --- */
+ /*0081:*/ 22, 21, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0086:*/ 0x00,0x07,0x00, /* .............###........ */
+ /*0089:*/ 0x3e,0x07,0x00, /* ..#####......###........ */
+ /*008c:*/ 0x7f,0x0e,0x00, /* .#######....###......... */
+ /*008f:*/ 0xe3,0x8e,0x00, /* ###...###...###......... */
+ /*0092:*/ 0xc1,0x9c,0x00, /* ##.....##..###.......... */
+ /*0095:*/ 0xc1,0x9c,0x00, /* ##.....##..###.......... */
+ /*0098:*/ 0xe3,0xb8,0x00, /* ###...###.###........... */
+ /*009b:*/ 0x7f,0x38,0x00, /* .#######..###........... */
+ /*009e:*/ 0x3e,0x70,0x00, /* ..#####..###............ */
+ /*00a1:*/ 0x00,0x70,0x00, /* .........###............ */
+ /*00a4:*/ 0x00,0xe3,0xe0, /* ........###...#####..... */
+ /*00a7:*/ 0x00,0xe7,0xf0, /* ........###..#######.... */
+ /*00aa:*/ 0x01,0xce,0x38, /* .......###..###...###... */
+ /*00ad:*/ 0x01,0xcc,0x18, /* .......###..##.....##... */
+ /*00b0:*/ 0x03,0x8c,0x18, /* ......###...##.....##... */
+ /*00b3:*/ 0x03,0x8e,0x38, /* ......###...###...###... */
+ /*00b6:*/ 0x07,0x07,0xf0, /* .....###.....#######.... */
+ /*00b9:*/ 0x07,0x03,0xe0, /* .....###......#####..... */
+/* --- new character ampersand (38) starting at offset 0x00bc --- */
+ /*00bc:*/ 18, 16, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00c1:*/ 0x0f,0x80, /* ....#####....... */
+ /*00c3:*/ 0x1f,0xc0, /* ...#######...... */
+ /*00c5:*/ 0x3d,0xe0, /* ..####.####..... */
+ /*00c7:*/ 0x38,0xe0, /* ..###...###..... */
+ /*00c9:*/ 0x38,0xe0, /* ..###...###..... */
+ /*00cb:*/ 0x38,0xe0, /* ..###...###..... */
+ /*00cd:*/ 0x1d,0xc0, /* ...###.###...... */
+ /*00cf:*/ 0x0f,0x80, /* ....#####....... */
+ /*00d1:*/ 0x1f,0x00, /* ...#####........ */
+ /*00d3:*/ 0x3f,0x9c, /* ..#######..###.. */
+ /*00d5:*/ 0x7b,0xdc, /* .####.####.###.. */
+ /*00d7:*/ 0x71,0xfc, /* .###...#######.. */
+ /*00d9:*/ 0xe0,0xf8, /* ###.....#####... */
+ /*00db:*/ 0xe0,0x70, /* ###......###.... */
+ /*00dd:*/ 0xe0,0xf8, /* ###.....#####... */
+ /*00df:*/ 0xf1,0xfc, /* ####...#######.. */
+ /*00e1:*/ 0x7f,0xce, /* .#########..###. */
+ /*00e3:*/ 0x1f,0x87, /* ...######....### */
+/* --- new character quotesingle (39) starting at offset 0x00e5 --- */
+ /*00e5:*/ 6, 2, 6, 2, 13, /* width and bbox (w,h,x,y) */
+ /*00ea:*/ 0xc0, /* ##...... */
+ /*00eb:*/ 0xc0, /* ##...... */
+ /*00ec:*/ 0xc0, /* ##...... */
+ /*00ed:*/ 0xc0, /* ##...... */
+ /*00ee:*/ 0xc0, /* ##...... */
+ /*00ef:*/ 0x80, /* #....... */
+/* --- new character parenleft (40) starting at offset 0x00f0 --- */
+ /*00f0:*/ 8, 6, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*00f5:*/ 0x0c, /* ....##.. */
+ /*00f6:*/ 0x1c, /* ...###.. */
+ /*00f7:*/ 0x38, /* ..###... */
+ /*00f8:*/ 0x38, /* ..###... */
+ /*00f9:*/ 0x70, /* .###.... */
+ /*00fa:*/ 0x70, /* .###.... */
+ /*00fb:*/ 0x60, /* .##..... */
+ /*00fc:*/ 0xe0, /* ###..... */
+ /*00fd:*/ 0xe0, /* ###..... */
+ /*00fe:*/ 0xe0, /* ###..... */
+ /*00ff:*/ 0xe0, /* ###..... */
+ /*0100:*/ 0xe0, /* ###..... */
+ /*0101:*/ 0xe0, /* ###..... */
+ /*0102:*/ 0xe0, /* ###..... */
+ /*0103:*/ 0xe0, /* ###..... */
+ /*0104:*/ 0xe0, /* ###..... */
+ /*0105:*/ 0xe0, /* ###..... */
+ /*0106:*/ 0x60, /* .##..... */
+ /*0107:*/ 0x70, /* .###.... */
+ /*0108:*/ 0x70, /* .###.... */
+ /*0109:*/ 0x38, /* ..###... */
+ /*010a:*/ 0x38, /* ..###... */
+ /*010b:*/ 0x1c, /* ...###.. */
+ /*010c:*/ 0x0c, /* ....##.. */
+/* --- new character parenright (41) starting at offset 0x010d --- */
+ /*010d:*/ 8, 6, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0112:*/ 0xc0, /* ##...... */
+ /*0113:*/ 0xe0, /* ###..... */
+ /*0114:*/ 0x70, /* .###.... */
+ /*0115:*/ 0x70, /* .###.... */
+ /*0116:*/ 0x38, /* ..###... */
+ /*0117:*/ 0x38, /* ..###... */
+ /*0118:*/ 0x18, /* ...##... */
+ /*0119:*/ 0x1c, /* ...###.. */
+ /*011a:*/ 0x1c, /* ...###.. */
+ /*011b:*/ 0x1c, /* ...###.. */
+ /*011c:*/ 0x1c, /* ...###.. */
+ /*011d:*/ 0x1c, /* ...###.. */
+ /*011e:*/ 0x1c, /* ...###.. */
+ /*011f:*/ 0x1c, /* ...###.. */
+ /*0120:*/ 0x1c, /* ...###.. */
+ /*0121:*/ 0x1c, /* ...###.. */
+ /*0122:*/ 0x1c, /* ...###.. */
+ /*0123:*/ 0x18, /* ...##... */
+ /*0124:*/ 0x38, /* ..###... */
+ /*0125:*/ 0x38, /* ..###... */
+ /*0126:*/ 0x70, /* .###.... */
+ /*0127:*/ 0x70, /* .###.... */
+ /*0128:*/ 0xe0, /* ###..... */
+ /*0129:*/ 0xc0, /* ##...... */
+/* --- new character asterisk (42) starting at offset 0x012a --- */
+ /*012a:*/ 10, 8, 7, 1, 12, /* width and bbox (w,h,x,y) */
+ /*012f:*/ 0x18, /* ...##... */
+ /*0130:*/ 0x18, /* ...##... */
+ /*0131:*/ 0xdb, /* ##.##.## */
+ /*0132:*/ 0xff, /* ######## */
+ /*0133:*/ 0x3c, /* ..####.. */
+ /*0134:*/ 0x66, /* .##..##. */
+ /*0135:*/ 0x66, /* .##..##. */
+/* --- new character plus (43) starting at offset 0x0136 --- */
+ /*0136:*/ 15, 11, 12, 2, 1, /* width and bbox (w,h,x,y) */
+ /*013b:*/ 0x0e,0x00, /* ....###......... */
+ /*013d:*/ 0x0e,0x00, /* ....###......... */
+ /*013f:*/ 0x0e,0x00, /* ....###......... */
+ /*0141:*/ 0x0e,0x00, /* ....###......... */
+ /*0143:*/ 0x0e,0x00, /* ....###......... */
+ /*0145:*/ 0xff,0xe0, /* ###########..... */
+ /*0147:*/ 0xff,0xe0, /* ###########..... */
+ /*0149:*/ 0x0e,0x00, /* ....###......... */
+ /*014b:*/ 0x0e,0x00, /* ....###......... */
+ /*014d:*/ 0x0e,0x00, /* ....###......... */
+ /*014f:*/ 0x0e,0x00, /* ....###......... */
+ /*0151:*/ 0x0e,0x00, /* ....###......... */
+/* --- new character comma (44) starting at offset 0x0153 --- */
+ /*0153:*/ 7, 3, 6, 2, -3, /* width and bbox (w,h,x,y) */
+ /*0158:*/ 0xe0, /* ###..... */
+ /*0159:*/ 0xe0, /* ###..... */
+ /*015a:*/ 0xe0, /* ###..... */
+ /*015b:*/ 0x60, /* .##..... */
+ /*015c:*/ 0x60, /* .##..... */
+ /*015d:*/ 0xc0, /* ##...... */
+/* --- new character hyphen (45) starting at offset 0x015e --- */
+ /*015e:*/ 8, 7, 3, 0, 6, /* width and bbox (w,h,x,y) */
+ /*0163:*/ 0xfe, /* #######. */
+ /*0164:*/ 0xfe, /* #######. */
+ /*0165:*/ 0xfe, /* #######. */
+/* --- new character period (46) starting at offset 0x0166 --- */
+ /*0166:*/ 7, 3, 3, 2, 0, /* width and bbox (w,h,x,y) */
+ /*016b:*/ 0xe0, /* ###..... */
+ /*016c:*/ 0xe0, /* ###..... */
+ /*016d:*/ 0xe0, /* ###..... */
+/* --- new character slash (47) starting at offset 0x016e --- */
+ /*016e:*/ 8, 8, 19, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0173:*/ 0x07, /* .....### */
+ /*0174:*/ 0x07, /* .....### */
+ /*0175:*/ 0x06, /* .....##. */
+ /*0176:*/ 0x06, /* .....##. */
+ /*0177:*/ 0x0e, /* ....###. */
+ /*0178:*/ 0x0c, /* ....##.. */
+ /*0179:*/ 0x0c, /* ....##.. */
+ /*017a:*/ 0x1c, /* ...###.. */
+ /*017b:*/ 0x1c, /* ...###.. */
+ /*017c:*/ 0x18, /* ...##... */
+ /*017d:*/ 0x18, /* ...##... */
+ /*017e:*/ 0x38, /* ..###... */
+ /*017f:*/ 0x30, /* ..##.... */
+ /*0180:*/ 0x30, /* ..##.... */
+ /*0181:*/ 0x70, /* .###.... */
+ /*0182:*/ 0x60, /* .##..... */
+ /*0183:*/ 0x60, /* .##..... */
+ /*0184:*/ 0xe0, /* ###..... */
+ /*0185:*/ 0xe0, /* ###..... */
+/* --- new character zero (48) starting at offset 0x0186 --- */
+ /*0186:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*018b:*/ 0x1f,0x80, /* ...######....... */
+ /*018d:*/ 0x3f,0xc0, /* ..########...... */
+ /*018f:*/ 0x79,0xe0, /* .####..####..... */
+ /*0191:*/ 0x70,0xe0, /* .###....###..... */
+ /*0193:*/ 0x70,0xe0, /* .###....###..... */
+ /*0195:*/ 0xe0,0x70, /* ###......###.... */
+ /*0197:*/ 0xe0,0x70, /* ###......###.... */
+ /*0199:*/ 0xe0,0x70, /* ###......###.... */
+ /*019b:*/ 0xe0,0x70, /* ###......###.... */
+ /*019d:*/ 0xe0,0x70, /* ###......###.... */
+ /*019f:*/ 0xe0,0x70, /* ###......###.... */
+ /*01a1:*/ 0xe0,0x70, /* ###......###.... */
+ /*01a3:*/ 0xe0,0x70, /* ###......###.... */
+ /*01a5:*/ 0x70,0xe0, /* .###....###..... */
+ /*01a7:*/ 0x70,0xe0, /* .###....###..... */
+ /*01a9:*/ 0x79,0xe0, /* .####..####..... */
+ /*01ab:*/ 0x3f,0xc0, /* ..########...... */
+ /*01ad:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character one (49) starting at offset 0x01af --- */
+ /*01af:*/ 13, 7, 18, 2, 0, /* width and bbox (w,h,x,y) */
+ /*01b4:*/ 0x0e, /* ....###. */
+ /*01b5:*/ 0x0e, /* ....###. */
+ /*01b6:*/ 0x1e, /* ...####. */
+ /*01b7:*/ 0xfe, /* #######. */
+ /*01b8:*/ 0xfe, /* #######. */
+ /*01b9:*/ 0x0e, /* ....###. */
+ /*01ba:*/ 0x0e, /* ....###. */
+ /*01bb:*/ 0x0e, /* ....###. */
+ /*01bc:*/ 0x0e, /* ....###. */
+ /*01bd:*/ 0x0e, /* ....###. */
+ /*01be:*/ 0x0e, /* ....###. */
+ /*01bf:*/ 0x0e, /* ....###. */
+ /*01c0:*/ 0x0e, /* ....###. */
+ /*01c1:*/ 0x0e, /* ....###. */
+ /*01c2:*/ 0x0e, /* ....###. */
+ /*01c3:*/ 0x0e, /* ....###. */
+ /*01c4:*/ 0x0e, /* ....###. */
+ /*01c5:*/ 0x0e, /* ....###. */
+/* --- new character two (50) starting at offset 0x01c6 --- */
+ /*01c6:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01cb:*/ 0x1f,0x00, /* ...#####........ */
+ /*01cd:*/ 0x7f,0xc0, /* .#########...... */
+ /*01cf:*/ 0x71,0xe0, /* .###...####..... */
+ /*01d1:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*01d3:*/ 0xe0,0x70, /* ###......###.... */
+ /*01d5:*/ 0xe0,0x70, /* ###......###.... */
+ /*01d7:*/ 0x00,0x70, /* .........###.... */
+ /*01d9:*/ 0x00,0xe0, /* ........###..... */
+ /*01db:*/ 0x01,0xe0, /* .......####..... */
+ /*01dd:*/ 0x03,0xc0, /* ......####...... */
+ /*01df:*/ 0x07,0x80, /* .....####....... */
+ /*01e1:*/ 0x1f,0x00, /* ...#####........ */
+ /*01e3:*/ 0x3c,0x00, /* ..####.......... */
+ /*01e5:*/ 0x78,0x00, /* .####........... */
+ /*01e7:*/ 0xf0,0x00, /* ####............ */
+ /*01e9:*/ 0xe0,0x00, /* ###............. */
+ /*01eb:*/ 0xff,0xf0, /* ############.... */
+ /*01ed:*/ 0xff,0xf0, /* ############.... */
+/* --- new character three (51) starting at offset 0x01ef --- */
+ /*01ef:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*01f4:*/ 0x1f,0x00, /* ...#####........ */
+ /*01f6:*/ 0x7f,0xc0, /* .#########...... */
+ /*01f8:*/ 0x71,0xc0, /* .###...###...... */
+ /*01fa:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*01fc:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*01fe:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0200:*/ 0x00,0xe0, /* ........###..... */
+ /*0202:*/ 0x01,0xc0, /* .......###...... */
+ /*0204:*/ 0x0f,0x80, /* ....#####....... */
+ /*0206:*/ 0x0f,0xe0, /* ....#######..... */
+ /*0208:*/ 0x00,0xe0, /* ........###..... */
+ /*020a:*/ 0x00,0x70, /* .........###.... */
+ /*020c:*/ 0x00,0x70, /* .........###.... */
+ /*020e:*/ 0xe0,0x70, /* ###......###.... */
+ /*0210:*/ 0xe0,0xf0, /* ###.....####.... */
+ /*0212:*/ 0x71,0xe0, /* .###...####..... */
+ /*0214:*/ 0x7f,0xe0, /* .##########..... */
+ /*0216:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character four (52) starting at offset 0x0218 --- */
+ /*0218:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*021d:*/ 0x01,0xc0, /* .......###...... */
+ /*021f:*/ 0x03,0xc0, /* ......####...... */
+ /*0221:*/ 0x03,0xc0, /* ......####...... */
+ /*0223:*/ 0x07,0xc0, /* .....#####...... */
+ /*0225:*/ 0x07,0xc0, /* .....#####...... */
+ /*0227:*/ 0x0d,0xc0, /* ....##.###...... */
+ /*0229:*/ 0x1d,0xc0, /* ...###.###...... */
+ /*022b:*/ 0x19,0xc0, /* ...##..###...... */
+ /*022d:*/ 0x31,0xc0, /* ..##...###...... */
+ /*022f:*/ 0x71,0xc0, /* .###...###...... */
+ /*0231:*/ 0x61,0xc0, /* .##....###...... */
+ /*0233:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0235:*/ 0xff,0xf0, /* ############.... */
+ /*0237:*/ 0xff,0xf0, /* ############.... */
+ /*0239:*/ 0x01,0xc0, /* .......###...... */
+ /*023b:*/ 0x01,0xc0, /* .......###...... */
+ /*023d:*/ 0x01,0xc0, /* .......###...... */
+ /*023f:*/ 0x01,0xc0, /* .......###...... */
+/* --- new character five (53) starting at offset 0x0241 --- */
+ /*0241:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0246:*/ 0x7f,0xe0, /* .##########..... */
+ /*0248:*/ 0x7f,0xe0, /* .##########..... */
+ /*024a:*/ 0x70,0x00, /* .###............ */
+ /*024c:*/ 0x70,0x00, /* .###............ */
+ /*024e:*/ 0x70,0x00, /* .###............ */
+ /*0250:*/ 0x70,0x00, /* .###............ */
+ /*0252:*/ 0x7f,0x80, /* .########....... */
+ /*0254:*/ 0x7f,0xc0, /* .#########...... */
+ /*0256:*/ 0x71,0xe0, /* .###...####..... */
+ /*0258:*/ 0x00,0xe0, /* ........###..... */
+ /*025a:*/ 0x00,0x70, /* .........###.... */
+ /*025c:*/ 0x00,0x70, /* .........###.... */
+ /*025e:*/ 0x00,0x70, /* .........###.... */
+ /*0260:*/ 0xe0,0x70, /* ###......###.... */
+ /*0262:*/ 0xe0,0xf0, /* ###.....####.... */
+ /*0264:*/ 0xf1,0xe0, /* ####...####..... */
+ /*0266:*/ 0x7f,0xc0, /* .#########...... */
+ /*0268:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character six (54) starting at offset 0x026a --- */
+ /*026a:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*026f:*/ 0x0f,0x80, /* ....#####....... */
+ /*0271:*/ 0x3f,0xe0, /* ..#########..... */
+ /*0273:*/ 0x78,0xe0, /* .####...###..... */
+ /*0275:*/ 0x70,0x70, /* .###.....###.... */
+ /*0277:*/ 0xe0,0x70, /* ###......###.... */
+ /*0279:*/ 0xe0,0x00, /* ###............. */
+ /*027b:*/ 0xe0,0x00, /* ###............. */
+ /*027d:*/ 0xef,0x00, /* ###.####........ */
+ /*027f:*/ 0xff,0xc0, /* ##########...... */
+ /*0281:*/ 0xf9,0xe0, /* #####..####..... */
+ /*0283:*/ 0xf0,0xe0, /* ####....###..... */
+ /*0285:*/ 0xe0,0x70, /* ###......###.... */
+ /*0287:*/ 0xe0,0x70, /* ###......###.... */
+ /*0289:*/ 0xe0,0x70, /* ###......###.... */
+ /*028b:*/ 0x70,0xe0, /* .###....###..... */
+ /*028d:*/ 0x79,0xe0, /* .####..####..... */
+ /*028f:*/ 0x3f,0xc0, /* ..########...... */
+ /*0291:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character seven (55) starting at offset 0x0293 --- */
+ /*0293:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0298:*/ 0xff,0xf0, /* ############.... */
+ /*029a:*/ 0xff,0xf0, /* ############.... */
+ /*029c:*/ 0x00,0xf0, /* ........####.... */
+ /*029e:*/ 0x00,0xe0, /* ........###..... */
+ /*02a0:*/ 0x01,0xc0, /* .......###...... */
+ /*02a2:*/ 0x01,0xc0, /* .......###...... */
+ /*02a4:*/ 0x03,0x80, /* ......###....... */
+ /*02a6:*/ 0x03,0x80, /* ......###....... */
+ /*02a8:*/ 0x07,0x00, /* .....###........ */
+ /*02aa:*/ 0x07,0x00, /* .....###........ */
+ /*02ac:*/ 0x0e,0x00, /* ....###......... */
+ /*02ae:*/ 0x0e,0x00, /* ....###......... */
+ /*02b0:*/ 0x1e,0x00, /* ...####......... */
+ /*02b2:*/ 0x1c,0x00, /* ...###.......... */
+ /*02b4:*/ 0x1c,0x00, /* ...###.......... */
+ /*02b6:*/ 0x3c,0x00, /* ..####.......... */
+ /*02b8:*/ 0x38,0x00, /* ..###........... */
+ /*02ba:*/ 0x38,0x00, /* ..###........... */
+/* --- new character eight (56) starting at offset 0x02bc --- */
+ /*02bc:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02c1:*/ 0x0f,0x00, /* ....####........ */
+ /*02c3:*/ 0x3f,0xc0, /* ..########...... */
+ /*02c5:*/ 0x39,0xc0, /* ..###..###...... */
+ /*02c7:*/ 0x70,0xe0, /* .###....###..... */
+ /*02c9:*/ 0x70,0xe0, /* .###....###..... */
+ /*02cb:*/ 0x70,0xe0, /* .###....###..... */
+ /*02cd:*/ 0x70,0xe0, /* .###....###..... */
+ /*02cf:*/ 0x39,0xc0, /* ..###..###...... */
+ /*02d1:*/ 0x1f,0x80, /* ...######....... */
+ /*02d3:*/ 0x3f,0xc0, /* ..########...... */
+ /*02d5:*/ 0x70,0xe0, /* .###....###..... */
+ /*02d7:*/ 0xe0,0x70, /* ###......###.... */
+ /*02d9:*/ 0xe0,0x70, /* ###......###.... */
+ /*02db:*/ 0xe0,0x70, /* ###......###.... */
+ /*02dd:*/ 0xe0,0x70, /* ###......###.... */
+ /*02df:*/ 0x70,0xe0, /* .###....###..... */
+ /*02e1:*/ 0x7f,0xe0, /* .##########..... */
+ /*02e3:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character nine (57) starting at offset 0x02e5 --- */
+ /*02e5:*/ 13, 12, 18, 0, 0, /* width and bbox (w,h,x,y) */
+ /*02ea:*/ 0x1f,0x80, /* ...######....... */
+ /*02ec:*/ 0x7f,0xc0, /* .#########...... */
+ /*02ee:*/ 0x79,0xe0, /* .####..####..... */
+ /*02f0:*/ 0xf0,0xe0, /* ####....###..... */
+ /*02f2:*/ 0xe0,0x70, /* ###......###.... */
+ /*02f4:*/ 0xe0,0x70, /* ###......###.... */
+ /*02f6:*/ 0xe0,0x70, /* ###......###.... */
+ /*02f8:*/ 0xe0,0x70, /* ###......###.... */
+ /*02fa:*/ 0xf0,0xf0, /* ####....####.... */
+ /*02fc:*/ 0x79,0xf0, /* .####..#####.... */
+ /*02fe:*/ 0x7f,0xf0, /* .###########.... */
+ /*0300:*/ 0x1f,0x70, /* ...#####.###.... */
+ /*0302:*/ 0x00,0x70, /* .........###.... */
+ /*0304:*/ 0x00,0x70, /* .........###.... */
+ /*0306:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0308:*/ 0xf3,0xe0, /* ####..#####..... */
+ /*030a:*/ 0x7f,0xc0, /* .#########...... */
+ /*030c:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character colon (58) starting at offset 0x030e --- */
+ /*030e:*/ 7, 3, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0313:*/ 0xe0, /* ###..... */
+ /*0314:*/ 0xe0, /* ###..... */
+ /*0315:*/ 0xe0, /* ###..... */
+ /*0316:*/ 0x00, /* ........ */
+ /*0317:*/ 0x00, /* ........ */
+ /*0318:*/ 0x00, /* ........ */
+ /*0319:*/ 0x00, /* ........ */
+ /*031a:*/ 0x00, /* ........ */
+ /*031b:*/ 0x00, /* ........ */
+ /*031c:*/ 0x00, /* ........ */
+ /*031d:*/ 0x00, /* ........ */
+ /*031e:*/ 0xe0, /* ###..... */
+ /*031f:*/ 0xe0, /* ###..... */
+ /*0320:*/ 0xe0, /* ###..... */
+/* --- new character semicolon (59) starting at offset 0x0321 --- */
+ /*0321:*/ 7, 3, 17, 2, -3, /* width and bbox (w,h,x,y) */
+ /*0326:*/ 0xe0, /* ###..... */
+ /*0327:*/ 0xe0, /* ###..... */
+ /*0328:*/ 0xe0, /* ###..... */
+ /*0329:*/ 0x00, /* ........ */
+ /*032a:*/ 0x00, /* ........ */
+ /*032b:*/ 0x00, /* ........ */
+ /*032c:*/ 0x00, /* ........ */
+ /*032d:*/ 0x00, /* ........ */
+ /*032e:*/ 0x00, /* ........ */
+ /*032f:*/ 0x00, /* ........ */
+ /*0330:*/ 0x00, /* ........ */
+ /*0331:*/ 0xe0, /* ###..... */
+ /*0332:*/ 0xe0, /* ###..... */
+ /*0333:*/ 0xe0, /* ###..... */
+ /*0334:*/ 0x60, /* .##..... */
+ /*0335:*/ 0x60, /* .##..... */
+ /*0336:*/ 0xc0, /* ##...... */
+/* --- new character less (60) starting at offset 0x0337 --- */
+ /*0337:*/ 15, 13, 12, 0, 1, /* width and bbox (w,h,x,y) */
+ /*033c:*/ 0x00,0x38, /* ..........###... */
+ /*033e:*/ 0x00,0xf8, /* ........#####... */
+ /*0340:*/ 0x03,0xe0, /* ......#####..... */
+ /*0342:*/ 0x0f,0x80, /* ....#####....... */
+ /*0344:*/ 0x3e,0x00, /* ..#####......... */
+ /*0346:*/ 0xf0,0x00, /* ####............ */
+ /*0348:*/ 0xf0,0x00, /* ####............ */
+ /*034a:*/ 0x3e,0x00, /* ..#####......... */
+ /*034c:*/ 0x0f,0x80, /* ....#####....... */
+ /*034e:*/ 0x03,0xe0, /* ......#####..... */
+ /*0350:*/ 0x00,0xf8, /* ........#####... */
+ /*0352:*/ 0x00,0x38, /* ..........###... */
+/* --- new character equal (61) starting at offset 0x0354 --- */
+ /*0354:*/ 14, 10, 6, 2, 4, /* width and bbox (w,h,x,y) */
+ /*0359:*/ 0xff,0xc0, /* ##########...... */
+ /*035b:*/ 0xff,0xc0, /* ##########...... */
+ /*035d:*/ 0x00,0x00, /* ................ */
+ /*035f:*/ 0x00,0x00, /* ................ */
+ /*0361:*/ 0xff,0xc0, /* ##########...... */
+ /*0363:*/ 0xff,0xc0, /* ##########...... */
+/* --- new character greater (62) starting at offset 0x0365 --- */
+ /*0365:*/ 14, 13, 12, 0, 1, /* width and bbox (w,h,x,y) */
+ /*036a:*/ 0xe0,0x00, /* ###............. */
+ /*036c:*/ 0xf8,0x00, /* #####........... */
+ /*036e:*/ 0x3e,0x00, /* ..#####......... */
+ /*0370:*/ 0x0f,0x80, /* ....#####....... */
+ /*0372:*/ 0x03,0xe0, /* ......#####..... */
+ /*0374:*/ 0x00,0x78, /* .........####... */
+ /*0376:*/ 0x00,0x78, /* .........####... */
+ /*0378:*/ 0x03,0xe0, /* ......#####..... */
+ /*037a:*/ 0x0f,0x80, /* ....#####....... */
+ /*037c:*/ 0x3e,0x00, /* ..#####......... */
+ /*037e:*/ 0xf8,0x00, /* #####........... */
+ /*0380:*/ 0xe0,0x00, /* ###............. */
+/* --- new character question (63) starting at offset 0x0382 --- */
+ /*0382:*/ 15, 11, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0387:*/ 0x1f,0x80, /* ...######....... */
+ /*0389:*/ 0x7f,0xc0, /* .#########...... */
+ /*038b:*/ 0x79,0xe0, /* .####..####..... */
+ /*038d:*/ 0xf0,0xe0, /* ####....###..... */
+ /*038f:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0391:*/ 0xe1,0xe0, /* ###....####..... */
+ /*0393:*/ 0x01,0xc0, /* .......###...... */
+ /*0395:*/ 0x03,0xc0, /* ......####...... */
+ /*0397:*/ 0x07,0x80, /* .....####....... */
+ /*0399:*/ 0x07,0x00, /* .....###........ */
+ /*039b:*/ 0x0e,0x00, /* ....###......... */
+ /*039d:*/ 0x0e,0x00, /* ....###......... */
+ /*039f:*/ 0x0e,0x00, /* ....###......... */
+ /*03a1:*/ 0x0e,0x00, /* ....###......... */
+ /*03a3:*/ 0x00,0x00, /* ................ */
+ /*03a5:*/ 0x00,0x00, /* ................ */
+ /*03a7:*/ 0x0e,0x00, /* ....###......... */
+ /*03a9:*/ 0x0e,0x00, /* ....###......... */
+ /*03ab:*/ 0x0e,0x00, /* ....###......... */
+/* --- new character at (64) starting at offset 0x03ad --- */
+ /*03ad:*/ 24, 22, 22, 1, -4, /* width and bbox (w,h,x,y) */
+ /*03b2:*/ 0x01,0xff,0x00, /* .......#########........ */
+ /*03b5:*/ 0x07,0xff,0xc0, /* .....#############...... */
+ /*03b8:*/ 0x0f,0x81,0xf0, /* ....#####......#####.... */
+ /*03bb:*/ 0x1e,0x00,0x78, /* ...####..........####... */
+ /*03be:*/ 0x3c,0x00,0x38, /* ..####............###... */
+ /*03c1:*/ 0x78,0x7d,0x9c, /* .####....#####.##..###.. */
+ /*03c4:*/ 0x70,0xff,0x9c, /* .###....#########..###.. */
+ /*03c7:*/ 0xf1,0xc7,0x1c, /* ####...###...###...###.. */
+ /*03ca:*/ 0xe3,0x87,0x1c, /* ###...###....###...###.. */
+ /*03cd:*/ 0xe3,0x0e,0x1c, /* ###...##....###....###.. */
+ /*03d0:*/ 0xe7,0x0e,0x38, /* ###..###....###...###... */
+ /*03d3:*/ 0xe7,0x0c,0x38, /* ###..###....##....###... */
+ /*03d6:*/ 0xe7,0x1c,0x70, /* ###..###...###...###.... */
+ /*03d9:*/ 0xe7,0x1c,0x70, /* ###..###...###...###.... */
+ /*03dc:*/ 0xe3,0x9d,0xe0, /* ###...###..###.####..... */
+ /*03df:*/ 0xf3,0xff,0xc0, /* ####..############...... */
+ /*03e2:*/ 0x71,0xf7,0x00, /* .###...#####.###........ */
+ /*03e5:*/ 0x78,0x00,0x00, /* .####................... */
+ /*03e8:*/ 0x3c,0x00,0x00, /* ..####.................. */
+ /*03eb:*/ 0x1f,0x07,0x00, /* ...#####.....###........ */
+ /*03ee:*/ 0x0f,0xff,0x00, /* ....############........ */
+ /*03f1:*/ 0x03,0xfc,0x00, /* ......########.......... */
+/* --- new character A (65) starting at offset 0x03f4 --- */
+ /*03f4:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*03f9:*/ 0x03,0xc0, /* ......####...... */
+ /*03fb:*/ 0x03,0xc0, /* ......####...... */
+ /*03fd:*/ 0x07,0xe0, /* .....######..... */
+ /*03ff:*/ 0x07,0xe0, /* .....######..... */
+ /*0401:*/ 0x0e,0x60, /* ....###..##..... */
+ /*0403:*/ 0x0e,0x70, /* ....###..###.... */
+ /*0405:*/ 0x0e,0x70, /* ....###..###.... */
+ /*0407:*/ 0x1c,0x38, /* ...###....###... */
+ /*0409:*/ 0x1c,0x38, /* ...###....###... */
+ /*040b:*/ 0x1c,0x38, /* ...###....###... */
+ /*040d:*/ 0x38,0x1c, /* ..###......###.. */
+ /*040f:*/ 0x38,0x1c, /* ..###......###.. */
+ /*0411:*/ 0x3f,0xfc, /* ..############.. */
+ /*0413:*/ 0x7f,0xfe, /* .##############. */
+ /*0415:*/ 0x70,0x0e, /* .###........###. */
+ /*0417:*/ 0x70,0x0e, /* .###........###. */
+ /*0419:*/ 0xe0,0x07, /* ###..........### */
+ /*041b:*/ 0xe0,0x07, /* ###..........### */
+ /*041d:*/ 0xe0,0x07, /* ###..........### */
+/* --- new character B (66) starting at offset 0x041f --- */
+ /*041f:*/ 18, 15, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0424:*/ 0xff,0xe0, /* ###########..... */
+ /*0426:*/ 0xff,0xf8, /* #############... */
+ /*0428:*/ 0xe0,0x78, /* ###......####... */
+ /*042a:*/ 0xe0,0x1c, /* ###........###.. */
+ /*042c:*/ 0xe0,0x1c, /* ###........###.. */
+ /*042e:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0430:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0432:*/ 0xe0,0x38, /* ###.......###... */
+ /*0434:*/ 0xff,0xf0, /* ############.... */
+ /*0436:*/ 0xff,0xf8, /* #############... */
+ /*0438:*/ 0xe0,0x1c, /* ###........###.. */
+ /*043a:*/ 0xe0,0x0e, /* ###.........###. */
+ /*043c:*/ 0xe0,0x0e, /* ###.........###. */
+ /*043e:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0440:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0442:*/ 0xe0,0x1e, /* ###........####. */
+ /*0444:*/ 0xe0,0x7c, /* ###......#####.. */
+ /*0446:*/ 0xff,0xf8, /* #############... */
+ /*0448:*/ 0xff,0xe0, /* ###########..... */
+/* --- new character C (67) starting at offset 0x044a --- */
+ /*044a:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*044f:*/ 0x07,0xf0, /* .....#######.... */
+ /*0451:*/ 0x1f,0xfc, /* ...###########.. */
+ /*0453:*/ 0x3e,0x3e, /* ..#####...#####. */
+ /*0455:*/ 0x78,0x0f, /* .####.......#### */
+ /*0457:*/ 0x70,0x07, /* .###.........### */
+ /*0459:*/ 0xf0,0x00, /* ####............ */
+ /*045b:*/ 0xe0,0x00, /* ###............. */
+ /*045d:*/ 0xe0,0x00, /* ###............. */
+ /*045f:*/ 0xe0,0x00, /* ###............. */
+ /*0461:*/ 0xe0,0x00, /* ###............. */
+ /*0463:*/ 0xe0,0x00, /* ###............. */
+ /*0465:*/ 0xe0,0x00, /* ###............. */
+ /*0467:*/ 0xe0,0x00, /* ###............. */
+ /*0469:*/ 0xf0,0x07, /* ####.........### */
+ /*046b:*/ 0x70,0x07, /* .###.........### */
+ /*046d:*/ 0x78,0x0f, /* .####.......#### */
+ /*046f:*/ 0x3e,0x3e, /* ..#####...#####. */
+ /*0471:*/ 0x1f,0xfc, /* ...###########.. */
+ /*0473:*/ 0x07,0xf0, /* .....#######.... */
+/* --- new character D (68) starting at offset 0x0475 --- */
+ /*0475:*/ 19, 16, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*047a:*/ 0xff,0xe0, /* ###########..... */
+ /*047c:*/ 0xff,0xf8, /* #############... */
+ /*047e:*/ 0xe0,0x7c, /* ###......#####.. */
+ /*0480:*/ 0xe0,0x1e, /* ###........####. */
+ /*0482:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0484:*/ 0xe0,0x0f, /* ###.........#### */
+ /*0486:*/ 0xe0,0x07, /* ###..........### */
+ /*0488:*/ 0xe0,0x07, /* ###..........### */
+ /*048a:*/ 0xe0,0x07, /* ###..........### */
+ /*048c:*/ 0xe0,0x07, /* ###..........### */
+ /*048e:*/ 0xe0,0x07, /* ###..........### */
+ /*0490:*/ 0xe0,0x07, /* ###..........### */
+ /*0492:*/ 0xe0,0x07, /* ###..........### */
+ /*0494:*/ 0xe0,0x0f, /* ###.........#### */
+ /*0496:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0498:*/ 0xe0,0x1e, /* ###........####. */
+ /*049a:*/ 0xe0,0x7c, /* ###......#####.. */
+ /*049c:*/ 0xff,0xf8, /* #############... */
+ /*049e:*/ 0xff,0xe0, /* ###########..... */
+/* --- new character E (69) starting at offset 0x04a0 --- */
+ /*04a0:*/ 16, 13, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*04a5:*/ 0xff,0xf0, /* ############.... */
+ /*04a7:*/ 0xff,0xf0, /* ############.... */
+ /*04a9:*/ 0xe0,0x00, /* ###............. */
+ /*04ab:*/ 0xe0,0x00, /* ###............. */
+ /*04ad:*/ 0xe0,0x00, /* ###............. */
+ /*04af:*/ 0xe0,0x00, /* ###............. */
+ /*04b1:*/ 0xe0,0x00, /* ###............. */
+ /*04b3:*/ 0xe0,0x00, /* ###............. */
+ /*04b5:*/ 0xff,0xe0, /* ###########..... */
+ /*04b7:*/ 0xff,0xe0, /* ###########..... */
+ /*04b9:*/ 0xe0,0x00, /* ###............. */
+ /*04bb:*/ 0xe0,0x00, /* ###............. */
+ /*04bd:*/ 0xe0,0x00, /* ###............. */
+ /*04bf:*/ 0xe0,0x00, /* ###............. */
+ /*04c1:*/ 0xe0,0x00, /* ###............. */
+ /*04c3:*/ 0xe0,0x00, /* ###............. */
+ /*04c5:*/ 0xe0,0x00, /* ###............. */
+ /*04c7:*/ 0xff,0xf8, /* #############... */
+ /*04c9:*/ 0xff,0xf8, /* #############... */
+/* --- new character F (70) starting at offset 0x04cb --- */
+ /*04cb:*/ 15, 12, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*04d0:*/ 0xff,0xf0, /* ############.... */
+ /*04d2:*/ 0xff,0xf0, /* ############.... */
+ /*04d4:*/ 0xe0,0x00, /* ###............. */
+ /*04d6:*/ 0xe0,0x00, /* ###............. */
+ /*04d8:*/ 0xe0,0x00, /* ###............. */
+ /*04da:*/ 0xe0,0x00, /* ###............. */
+ /*04dc:*/ 0xe0,0x00, /* ###............. */
+ /*04de:*/ 0xe0,0x00, /* ###............. */
+ /*04e0:*/ 0xff,0xe0, /* ###########..... */
+ /*04e2:*/ 0xff,0xe0, /* ###########..... */
+ /*04e4:*/ 0xe0,0x00, /* ###............. */
+ /*04e6:*/ 0xe0,0x00, /* ###............. */
+ /*04e8:*/ 0xe0,0x00, /* ###............. */
+ /*04ea:*/ 0xe0,0x00, /* ###............. */
+ /*04ec:*/ 0xe0,0x00, /* ###............. */
+ /*04ee:*/ 0xe0,0x00, /* ###............. */
+ /*04f0:*/ 0xe0,0x00, /* ###............. */
+ /*04f2:*/ 0xe0,0x00, /* ###............. */
+ /*04f4:*/ 0xe0,0x00, /* ###............. */
+/* --- new character G (71) starting at offset 0x04f6 --- */
+ /*04f6:*/ 19, 17, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04fb:*/ 0x07,0xf0,0x00, /* .....#######............ */
+ /*04fe:*/ 0x1f,0xfc,0x00, /* ...###########.......... */
+ /*0501:*/ 0x3e,0x3e,0x00, /* ..#####...#####......... */
+ /*0504:*/ 0x78,0x0f,0x00, /* .####.......####........ */
+ /*0507:*/ 0x70,0x07,0x00, /* .###.........###........ */
+ /*050a:*/ 0xf0,0x00,0x00, /* ####.................... */
+ /*050d:*/ 0xe0,0x00,0x00, /* ###..................... */
+ /*0510:*/ 0xe0,0x00,0x00, /* ###..................... */
+ /*0513:*/ 0xe0,0x00,0x00, /* ###..................... */
+ /*0516:*/ 0xe0,0x7f,0x80, /* ###......########....... */
+ /*0519:*/ 0xe0,0x7f,0x80, /* ###......########....... */
+ /*051c:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*051f:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*0522:*/ 0xf0,0x03,0x80, /* ####..........###....... */
+ /*0525:*/ 0x70,0x07,0x80, /* .###.........####....... */
+ /*0528:*/ 0x78,0x0f,0x80, /* .####.......#####....... */
+ /*052b:*/ 0x3e,0x3f,0x80, /* ..#####...#######....... */
+ /*052e:*/ 0x1f,0xfb,0x80, /* ...##########.###....... */
+ /*0531:*/ 0x07,0xf1,0x80, /* .....#######...##....... */
+/* --- new character H (72) starting at offset 0x0534 --- */
+ /*0534:*/ 19, 15, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0539:*/ 0xe0,0x0e, /* ###.........###. */
+ /*053b:*/ 0xe0,0x0e, /* ###.........###. */
+ /*053d:*/ 0xe0,0x0e, /* ###.........###. */
+ /*053f:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0541:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0543:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0545:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0547:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0549:*/ 0xff,0xfe, /* ###############. */
+ /*054b:*/ 0xff,0xfe, /* ###############. */
+ /*054d:*/ 0xe0,0x0e, /* ###.........###. */
+ /*054f:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0551:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0553:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0555:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0557:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0559:*/ 0xe0,0x0e, /* ###.........###. */
+ /*055b:*/ 0xe0,0x0e, /* ###.........###. */
+ /*055d:*/ 0xe0,0x0e, /* ###.........###. */
+/* --- new character I (73) starting at offset 0x055f --- */
+ /*055f:*/ 7, 3, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0564:*/ 0xe0, /* ###..... */
+ /*0565:*/ 0xe0, /* ###..... */
+ /*0566:*/ 0xe0, /* ###..... */
+ /*0567:*/ 0xe0, /* ###..... */
+ /*0568:*/ 0xe0, /* ###..... */
+ /*0569:*/ 0xe0, /* ###..... */
+ /*056a:*/ 0xe0, /* ###..... */
+ /*056b:*/ 0xe0, /* ###..... */
+ /*056c:*/ 0xe0, /* ###..... */
+ /*056d:*/ 0xe0, /* ###..... */
+ /*056e:*/ 0xe0, /* ###..... */
+ /*056f:*/ 0xe0, /* ###..... */
+ /*0570:*/ 0xe0, /* ###..... */
+ /*0571:*/ 0xe0, /* ###..... */
+ /*0572:*/ 0xe0, /* ###..... */
+ /*0573:*/ 0xe0, /* ###..... */
+ /*0574:*/ 0xe0, /* ###..... */
+ /*0575:*/ 0xe0, /* ###..... */
+ /*0576:*/ 0xe0, /* ###..... */
+/* --- new character J (74) starting at offset 0x0577 --- */
+ /*0577:*/ 14, 11, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*057c:*/ 0x00,0xe0, /* ........###..... */
+ /*057e:*/ 0x00,0xe0, /* ........###..... */
+ /*0580:*/ 0x00,0xe0, /* ........###..... */
+ /*0582:*/ 0x00,0xe0, /* ........###..... */
+ /*0584:*/ 0x00,0xe0, /* ........###..... */
+ /*0586:*/ 0x00,0xe0, /* ........###..... */
+ /*0588:*/ 0x00,0xe0, /* ........###..... */
+ /*058a:*/ 0x00,0xe0, /* ........###..... */
+ /*058c:*/ 0x00,0xe0, /* ........###..... */
+ /*058e:*/ 0x00,0xe0, /* ........###..... */
+ /*0590:*/ 0x00,0xe0, /* ........###..... */
+ /*0592:*/ 0x00,0xe0, /* ........###..... */
+ /*0594:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0596:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0598:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*059a:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*059c:*/ 0x71,0xe0, /* .###...####..... */
+ /*059e:*/ 0x7f,0xc0, /* .#########...... */
+ /*05a0:*/ 0x3f,0x80, /* ..#######....... */
+/* --- new character K (75) starting at offset 0x05a2 --- */
+ /*05a2:*/ 18, 16, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*05a7:*/ 0xe0,0x3c, /* ###.......####.. */
+ /*05a9:*/ 0xe0,0x78, /* ###......####... */
+ /*05ab:*/ 0xe0,0xf0, /* ###.....####.... */
+ /*05ad:*/ 0xe1,0xe0, /* ###....####..... */
+ /*05af:*/ 0xe3,0xc0, /* ###...####...... */
+ /*05b1:*/ 0xe7,0x80, /* ###..####....... */
+ /*05b3:*/ 0xef,0x00, /* ###.####........ */
+ /*05b5:*/ 0xfe,0x00, /* #######......... */
+ /*05b7:*/ 0xfe,0x00, /* #######......... */
+ /*05b9:*/ 0xff,0x00, /* ########........ */
+ /*05bb:*/ 0xf7,0x80, /* ####.####....... */
+ /*05bd:*/ 0xe3,0xc0, /* ###...####...... */
+ /*05bf:*/ 0xe1,0xe0, /* ###....####..... */
+ /*05c1:*/ 0xe0,0xf0, /* ###.....####.... */
+ /*05c3:*/ 0xe0,0x78, /* ###......####... */
+ /*05c5:*/ 0xe0,0x3c, /* ###.......####.. */
+ /*05c7:*/ 0xe0,0x1e, /* ###........####. */
+ /*05c9:*/ 0xe0,0x0f, /* ###.........#### */
+ /*05cb:*/ 0xe0,0x07, /* ###..........### */
+/* --- new character L (76) starting at offset 0x05cd --- */
+ /*05cd:*/ 15, 12, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*05d2:*/ 0xe0,0x00, /* ###............. */
+ /*05d4:*/ 0xe0,0x00, /* ###............. */
+ /*05d6:*/ 0xe0,0x00, /* ###............. */
+ /*05d8:*/ 0xe0,0x00, /* ###............. */
+ /*05da:*/ 0xe0,0x00, /* ###............. */
+ /*05dc:*/ 0xe0,0x00, /* ###............. */
+ /*05de:*/ 0xe0,0x00, /* ###............. */
+ /*05e0:*/ 0xe0,0x00, /* ###............. */
+ /*05e2:*/ 0xe0,0x00, /* ###............. */
+ /*05e4:*/ 0xe0,0x00, /* ###............. */
+ /*05e6:*/ 0xe0,0x00, /* ###............. */
+ /*05e8:*/ 0xe0,0x00, /* ###............. */
+ /*05ea:*/ 0xe0,0x00, /* ###............. */
+ /*05ec:*/ 0xe0,0x00, /* ###............. */
+ /*05ee:*/ 0xe0,0x00, /* ###............. */
+ /*05f0:*/ 0xe0,0x00, /* ###............. */
+ /*05f2:*/ 0xe0,0x00, /* ###............. */
+ /*05f4:*/ 0xff,0xf0, /* ############.... */
+ /*05f6:*/ 0xff,0xf0, /* ############.... */
+/* --- new character M (77) starting at offset 0x05f8 --- */
+ /*05f8:*/ 23, 19, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*05fd:*/ 0xe0,0x00,0xe0, /* ###.............###..... */
+ /*0600:*/ 0xf0,0x01,0xe0, /* ####...........####..... */
+ /*0603:*/ 0xf0,0x01,0xe0, /* ####...........####..... */
+ /*0606:*/ 0xf8,0x03,0xe0, /* #####.........#####..... */
+ /*0609:*/ 0xf8,0x03,0xe0, /* #####.........#####..... */
+ /*060c:*/ 0xfc,0x07,0xe0, /* ######.......######..... */
+ /*060f:*/ 0xec,0x06,0xe0, /* ###.##.......##.###..... */
+ /*0612:*/ 0xee,0x0e,0xe0, /* ###.###.....###.###..... */
+ /*0615:*/ 0xe6,0x0c,0xe0, /* ###..##.....##..###..... */
+ /*0618:*/ 0xe7,0x1c,0xe0, /* ###..###...###..###..... */
+ /*061b:*/ 0xe7,0x1c,0xe0, /* ###..###...###..###..... */
+ /*061e:*/ 0xe3,0x18,0xe0, /* ###...##...##...###..... */
+ /*0621:*/ 0xe3,0xb8,0xe0, /* ###...###.###...###..... */
+ /*0624:*/ 0xe3,0xb8,0xe0, /* ###...###.###...###..... */
+ /*0627:*/ 0xe1,0xf0,0xe0, /* ###....#####....###..... */
+ /*062a:*/ 0xe1,0xf0,0xe0, /* ###....#####....###..... */
+ /*062d:*/ 0xe0,0xe0,0xe0, /* ###.....###.....###..... */
+ /*0630:*/ 0xe0,0xe0,0xe0, /* ###.....###.....###..... */
+ /*0633:*/ 0xe0,0xe0,0xe0, /* ###.....###.....###..... */
+/* --- new character N (78) starting at offset 0x0636 --- */
+ /*0636:*/ 19, 15, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*063b:*/ 0xe0,0x0e, /* ###.........###. */
+ /*063d:*/ 0xf0,0x0e, /* ####........###. */
+ /*063f:*/ 0xf0,0x0e, /* ####........###. */
+ /*0641:*/ 0xf8,0x0e, /* #####.......###. */
+ /*0643:*/ 0xf8,0x0e, /* #####.......###. */
+ /*0645:*/ 0xfc,0x0e, /* ######......###. */
+ /*0647:*/ 0xee,0x0e, /* ###.###.....###. */
+ /*0649:*/ 0xee,0x0e, /* ###.###.....###. */
+ /*064b:*/ 0xe7,0x0e, /* ###..###....###. */
+ /*064d:*/ 0xe3,0x8e, /* ###...###...###. */
+ /*064f:*/ 0xe3,0x8e, /* ###...###...###. */
+ /*0651:*/ 0xe1,0xce, /* ###....###..###. */
+ /*0653:*/ 0xe0,0xce, /* ###.....##..###. */
+ /*0655:*/ 0xe0,0xee, /* ###.....###.###. */
+ /*0657:*/ 0xe0,0x7e, /* ###......######. */
+ /*0659:*/ 0xe0,0x3e, /* ###.......#####. */
+ /*065b:*/ 0xe0,0x3e, /* ###.......#####. */
+ /*065d:*/ 0xe0,0x1e, /* ###........####. */
+ /*065f:*/ 0xe0,0x0e, /* ###.........###. */
+/* --- new character O (79) starting at offset 0x0661 --- */
+ /*0661:*/ 19, 17, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0666:*/ 0x07,0xf0,0x00, /* .....#######............ */
+ /*0669:*/ 0x1f,0xfc,0x00, /* ...###########.......... */
+ /*066c:*/ 0x3e,0x3e,0x00, /* ..#####...#####......... */
+ /*066f:*/ 0x78,0x0f,0x00, /* .####.......####........ */
+ /*0672:*/ 0x70,0x07,0x00, /* .###.........###........ */
+ /*0675:*/ 0xf0,0x07,0x80, /* ####.........####....... */
+ /*0678:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*067b:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*067e:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*0681:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*0684:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*0687:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*068a:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*068d:*/ 0xf0,0x07,0x80, /* ####.........####....... */
+ /*0690:*/ 0x70,0x07,0x00, /* .###.........###........ */
+ /*0693:*/ 0x78,0x0f,0x00, /* .####.......####........ */
+ /*0696:*/ 0x3e,0x3e,0x00, /* ..#####...#####......... */
+ /*0699:*/ 0x1f,0xfc,0x00, /* ...###########.......... */
+ /*069c:*/ 0x07,0xf0,0x00, /* .....#######............ */
+/* --- new character P (80) starting at offset 0x069f --- */
+ /*069f:*/ 17, 14, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*06a4:*/ 0xff,0xe0, /* ###########..... */
+ /*06a6:*/ 0xff,0xf8, /* #############... */
+ /*06a8:*/ 0xe0,0x38, /* ###.......###... */
+ /*06aa:*/ 0xe0,0x1c, /* ###........###.. */
+ /*06ac:*/ 0xe0,0x1c, /* ###........###.. */
+ /*06ae:*/ 0xe0,0x1c, /* ###........###.. */
+ /*06b0:*/ 0xe0,0x1c, /* ###........###.. */
+ /*06b2:*/ 0xe0,0x38, /* ###.......###... */
+ /*06b4:*/ 0xff,0xf8, /* #############... */
+ /*06b6:*/ 0xff,0xf0, /* ############.... */
+ /*06b8:*/ 0xe0,0x00, /* ###............. */
+ /*06ba:*/ 0xe0,0x00, /* ###............. */
+ /*06bc:*/ 0xe0,0x00, /* ###............. */
+ /*06be:*/ 0xe0,0x00, /* ###............. */
+ /*06c0:*/ 0xe0,0x00, /* ###............. */
+ /*06c2:*/ 0xe0,0x00, /* ###............. */
+ /*06c4:*/ 0xe0,0x00, /* ###............. */
+ /*06c6:*/ 0xe0,0x00, /* ###............. */
+ /*06c8:*/ 0xe0,0x00, /* ###............. */
+/* --- new character Q (81) starting at offset 0x06ca --- */
+ /*06ca:*/ 19, 17, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*06cf:*/ 0x07,0xf0,0x00, /* .....#######............ */
+ /*06d2:*/ 0x1f,0xfc,0x00, /* ...###########.......... */
+ /*06d5:*/ 0x3e,0x3e,0x00, /* ..#####...#####......... */
+ /*06d8:*/ 0x78,0x0f,0x00, /* .####.......####........ */
+ /*06db:*/ 0x70,0x07,0x00, /* .###.........###........ */
+ /*06de:*/ 0xf0,0x07,0x80, /* ####.........####....... */
+ /*06e1:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06e4:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06e7:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06ea:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06ed:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06f0:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06f3:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*06f6:*/ 0xf0,0x07,0x80, /* ####.........####....... */
+ /*06f9:*/ 0x70,0xf7,0x00, /* .###....####.###........ */
+ /*06fc:*/ 0x78,0x7f,0x00, /* .####....#######........ */
+ /*06ff:*/ 0x3e,0x1e,0x00, /* ..#####....####......... */
+ /*0702:*/ 0x1f,0xff,0x00, /* ...#############........ */
+ /*0705:*/ 0x07,0xf7,0x80, /* .....#######.####....... */
+/* --- new character R (82) starting at offset 0x0708 --- */
+ /*0708:*/ 17, 14, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*070d:*/ 0xff,0xe0, /* ###########..... */
+ /*070f:*/ 0xff,0xf8, /* #############... */
+ /*0711:*/ 0xe0,0x38, /* ###.......###... */
+ /*0713:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0715:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0717:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0719:*/ 0xe0,0x1c, /* ###........###.. */
+ /*071b:*/ 0xe0,0x38, /* ###.......###... */
+ /*071d:*/ 0xff,0xf8, /* #############... */
+ /*071f:*/ 0xff,0xf0, /* ############.... */
+ /*0721:*/ 0xe0,0x78, /* ###......####... */
+ /*0723:*/ 0xe0,0x38, /* ###.......###... */
+ /*0725:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0727:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0729:*/ 0xe0,0x1c, /* ###........###.. */
+ /*072b:*/ 0xe0,0x1c, /* ###........###.. */
+ /*072d:*/ 0xe0,0x1c, /* ###........###.. */
+ /*072f:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0731:*/ 0xe0,0x1c, /* ###........###.. */
+/* --- new character S (83) starting at offset 0x0733 --- */
+ /*0733:*/ 17, 15, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0738:*/ 0x07,0xe0, /* .....######..... */
+ /*073a:*/ 0x1f,0xf8, /* ...##########... */
+ /*073c:*/ 0x3c,0x7c, /* ..####...#####.. */
+ /*073e:*/ 0x78,0x1c, /* .####......###.. */
+ /*0740:*/ 0x70,0x1c, /* .###.......###.. */
+ /*0742:*/ 0x70,0x00, /* .###............ */
+ /*0744:*/ 0x78,0x00, /* .####........... */
+ /*0746:*/ 0x3e,0x00, /* ..#####......... */
+ /*0748:*/ 0x1f,0xe0, /* ...########..... */
+ /*074a:*/ 0x03,0xf8, /* ......#######... */
+ /*074c:*/ 0x00,0x7c, /* .........#####.. */
+ /*074e:*/ 0x00,0x1e, /* ...........####. */
+ /*0750:*/ 0x00,0x0e, /* ............###. */
+ /*0752:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0754:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0756:*/ 0xf0,0x1e, /* ####.......####. */
+ /*0758:*/ 0x7c,0x7c, /* .#####...#####.. */
+ /*075a:*/ 0x3f,0xf8, /* ..###########... */
+ /*075c:*/ 0x0f,0xe0, /* ....#######..... */
+/* --- new character T (84) starting at offset 0x075e --- */
+ /*075e:*/ 15, 15, 19, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0763:*/ 0xff,0xfe, /* ###############. */
+ /*0765:*/ 0xff,0xfe, /* ###############. */
+ /*0767:*/ 0x03,0x80, /* ......###....... */
+ /*0769:*/ 0x03,0x80, /* ......###....... */
+ /*076b:*/ 0x03,0x80, /* ......###....... */
+ /*076d:*/ 0x03,0x80, /* ......###....... */
+ /*076f:*/ 0x03,0x80, /* ......###....... */
+ /*0771:*/ 0x03,0x80, /* ......###....... */
+ /*0773:*/ 0x03,0x80, /* ......###....... */
+ /*0775:*/ 0x03,0x80, /* ......###....... */
+ /*0777:*/ 0x03,0x80, /* ......###....... */
+ /*0779:*/ 0x03,0x80, /* ......###....... */
+ /*077b:*/ 0x03,0x80, /* ......###....... */
+ /*077d:*/ 0x03,0x80, /* ......###....... */
+ /*077f:*/ 0x03,0x80, /* ......###....... */
+ /*0781:*/ 0x03,0x80, /* ......###....... */
+ /*0783:*/ 0x03,0x80, /* ......###....... */
+ /*0785:*/ 0x03,0x80, /* ......###....... */
+ /*0787:*/ 0x03,0x80, /* ......###....... */
+/* --- new character U (85) starting at offset 0x0789 --- */
+ /*0789:*/ 19, 15, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*078e:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0790:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0792:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0794:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0796:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0798:*/ 0xe0,0x0e, /* ###.........###. */
+ /*079a:*/ 0xe0,0x0e, /* ###.........###. */
+ /*079c:*/ 0xe0,0x0e, /* ###.........###. */
+ /*079e:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07a0:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07a2:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07a4:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07a6:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07a8:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07aa:*/ 0xf0,0x1e, /* ####.......####. */
+ /*07ac:*/ 0x70,0x1c, /* .###.......###.. */
+ /*07ae:*/ 0x7c,0x7c, /* .#####...#####.. */
+ /*07b0:*/ 0x3f,0xf8, /* ..###########... */
+ /*07b2:*/ 0x0f,0xe0, /* ....#######..... */
+/* --- new character V (86) starting at offset 0x07b4 --- */
+ /*07b4:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*07b9:*/ 0xe0,0x07, /* ###..........### */
+ /*07bb:*/ 0xe0,0x07, /* ###..........### */
+ /*07bd:*/ 0xf0,0x0f, /* ####........#### */
+ /*07bf:*/ 0x70,0x0e, /* .###........###. */
+ /*07c1:*/ 0x78,0x1e, /* .####......####. */
+ /*07c3:*/ 0x38,0x1c, /* ..###......###.. */
+ /*07c5:*/ 0x38,0x1c, /* ..###......###.. */
+ /*07c7:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*07c9:*/ 0x1c,0x38, /* ...###....###... */
+ /*07cb:*/ 0x1c,0x38, /* ...###....###... */
+ /*07cd:*/ 0x1e,0x78, /* ...####..####... */
+ /*07cf:*/ 0x0e,0x70, /* ....###..###.... */
+ /*07d1:*/ 0x0e,0x70, /* ....###..###.... */
+ /*07d3:*/ 0x0e,0x70, /* ....###..###.... */
+ /*07d5:*/ 0x07,0xe0, /* .....######..... */
+ /*07d7:*/ 0x07,0xe0, /* .....######..... */
+ /*07d9:*/ 0x03,0xc0, /* ......####...... */
+ /*07db:*/ 0x03,0xc0, /* ......####...... */
+ /*07dd:*/ 0x03,0xc0, /* ......####...... */
+/* --- new character W (87) starting at offset 0x07df --- */
+ /*07df:*/ 23, 21, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*07e4:*/ 0xe0,0x70,0x38, /* ###......###......###... */
+ /*07e7:*/ 0xe0,0x70,0x38, /* ###......###......###... */
+ /*07ea:*/ 0xe0,0x70,0x38, /* ###......###......###... */
+ /*07ed:*/ 0xe0,0x70,0x38, /* ###......###......###... */
+ /*07f0:*/ 0x70,0xf8,0x70, /* .###....#####....###.... */
+ /*07f3:*/ 0x70,0xf8,0x70, /* .###....#####....###.... */
+ /*07f6:*/ 0x70,0xd8,0x70, /* .###....##.##....###.... */
+ /*07f9:*/ 0x71,0xdc,0x70, /* .###...###.###...###.... */
+ /*07fc:*/ 0x31,0xdc,0x60, /* ..##...###.###...##..... */
+ /*07ff:*/ 0x39,0xdc,0xe0, /* ..###..###.###..###..... */
+ /*0802:*/ 0x39,0x8c,0xe0, /* ..###..##...##..###..... */
+ /*0805:*/ 0x3b,0x8e,0xe0, /* ..###.###...###.###..... */
+ /*0808:*/ 0x1b,0x8e,0xc0, /* ...##.###...###.##...... */
+ /*080b:*/ 0x1b,0x8e,0xc0, /* ...##.###...###.##...... */
+ /*080e:*/ 0x1f,0x07,0xc0, /* ...#####.....#####...... */
+ /*0811:*/ 0x1f,0x07,0xc0, /* ...#####.....#####...... */
+ /*0814:*/ 0x0e,0x03,0x80, /* ....###.......###....... */
+ /*0817:*/ 0x0e,0x03,0x80, /* ....###.......###....... */
+ /*081a:*/ 0x0e,0x03,0x80, /* ....###.......###....... */
+/* --- new character X (88) starting at offset 0x081d --- */
+ /*081d:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0822:*/ 0xe0,0x07, /* ###..........### */
+ /*0824:*/ 0xf0,0x0f, /* ####........#### */
+ /*0826:*/ 0x78,0x1e, /* .####......####. */
+ /*0828:*/ 0x38,0x1c, /* ..###......###.. */
+ /*082a:*/ 0x1c,0x38, /* ...###....###... */
+ /*082c:*/ 0x0e,0x70, /* ....###..###.... */
+ /*082e:*/ 0x0f,0xf0, /* ....########.... */
+ /*0830:*/ 0x07,0xe0, /* .....######..... */
+ /*0832:*/ 0x03,0xc0, /* ......####...... */
+ /*0834:*/ 0x03,0xc0, /* ......####...... */
+ /*0836:*/ 0x07,0xe0, /* .....######..... */
+ /*0838:*/ 0x0f,0xf0, /* ....########.... */
+ /*083a:*/ 0x0e,0x70, /* ....###..###.... */
+ /*083c:*/ 0x1c,0x38, /* ...###....###... */
+ /*083e:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*0840:*/ 0x38,0x1c, /* ..###......###.. */
+ /*0842:*/ 0x70,0x0e, /* .###........###. */
+ /*0844:*/ 0xf0,0x0f, /* ####........#### */
+ /*0846:*/ 0xe0,0x07, /* ###..........### */
+/* --- new character Y (89) starting at offset 0x0848 --- */
+ /*0848:*/ 17, 15, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*084d:*/ 0xe0,0x0e, /* ###.........###. */
+ /*084f:*/ 0xf0,0x1e, /* ####.......####. */
+ /*0851:*/ 0x70,0x1c, /* .###.......###.. */
+ /*0853:*/ 0x78,0x3c, /* .####.....####.. */
+ /*0855:*/ 0x38,0x38, /* ..###.....###... */
+ /*0857:*/ 0x3c,0x78, /* ..####...####... */
+ /*0859:*/ 0x1c,0x70, /* ...###...###.... */
+ /*085b:*/ 0x1e,0xf0, /* ...####.####.... */
+ /*085d:*/ 0x0e,0xe0, /* ....###.###..... */
+ /*085f:*/ 0x0f,0xe0, /* ....#######..... */
+ /*0861:*/ 0x07,0xc0, /* .....#####...... */
+ /*0863:*/ 0x07,0xc0, /* .....#####...... */
+ /*0865:*/ 0x03,0x80, /* ......###....... */
+ /*0867:*/ 0x03,0x80, /* ......###....... */
+ /*0869:*/ 0x03,0x80, /* ......###....... */
+ /*086b:*/ 0x03,0x80, /* ......###....... */
+ /*086d:*/ 0x03,0x80, /* ......###....... */
+ /*086f:*/ 0x03,0x80, /* ......###....... */
+ /*0871:*/ 0x03,0x80, /* ......###....... */
+/* --- new character Z (90) starting at offset 0x0873 --- */
+ /*0873:*/ 16, 14, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0878:*/ 0xff,0xfc, /* ##############.. */
+ /*087a:*/ 0xff,0xfc, /* ##############.. */
+ /*087c:*/ 0x00,0x3c, /* ..........####.. */
+ /*087e:*/ 0x00,0x78, /* .........####... */
+ /*0880:*/ 0x00,0xf0, /* ........####.... */
+ /*0882:*/ 0x01,0xe0, /* .......####..... */
+ /*0884:*/ 0x01,0xe0, /* .......####..... */
+ /*0886:*/ 0x03,0xc0, /* ......####...... */
+ /*0888:*/ 0x07,0x80, /* .....####....... */
+ /*088a:*/ 0x07,0x80, /* .....####....... */
+ /*088c:*/ 0x0f,0x00, /* ....####........ */
+ /*088e:*/ 0x1e,0x00, /* ...####......... */
+ /*0890:*/ 0x1e,0x00, /* ...####......... */
+ /*0892:*/ 0x3c,0x00, /* ..####.......... */
+ /*0894:*/ 0x38,0x00, /* ..###........... */
+ /*0896:*/ 0x78,0x00, /* .####........... */
+ /*0898:*/ 0xf0,0x00, /* ####............ */
+ /*089a:*/ 0xff,0xfc, /* ##############.. */
+ /*089c:*/ 0xff,0xfc, /* ##############.. */
+/* --- new character bracketleft (91) starting at offset 0x089e --- */
+ /*089e:*/ 8, 5, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*08a3:*/ 0xf8, /* #####... */
+ /*08a4:*/ 0xf8, /* #####... */
+ /*08a5:*/ 0xe0, /* ###..... */
+ /*08a6:*/ 0xe0, /* ###..... */
+ /*08a7:*/ 0xe0, /* ###..... */
+ /*08a8:*/ 0xe0, /* ###..... */
+ /*08a9:*/ 0xe0, /* ###..... */
+ /*08aa:*/ 0xe0, /* ###..... */
+ /*08ab:*/ 0xe0, /* ###..... */
+ /*08ac:*/ 0xe0, /* ###..... */
+ /*08ad:*/ 0xe0, /* ###..... */
+ /*08ae:*/ 0xe0, /* ###..... */
+ /*08af:*/ 0xe0, /* ###..... */
+ /*08b0:*/ 0xe0, /* ###..... */
+ /*08b1:*/ 0xe0, /* ###..... */
+ /*08b2:*/ 0xe0, /* ###..... */
+ /*08b3:*/ 0xe0, /* ###..... */
+ /*08b4:*/ 0xe0, /* ###..... */
+ /*08b5:*/ 0xe0, /* ###..... */
+ /*08b6:*/ 0xe0, /* ###..... */
+ /*08b7:*/ 0xe0, /* ###..... */
+ /*08b8:*/ 0xe0, /* ###..... */
+ /*08b9:*/ 0xf8, /* #####... */
+ /*08ba:*/ 0xf8, /* #####... */
+/* --- new character backslash (92) starting at offset 0x08bb --- */
+ /*08bb:*/ 8, 8, 19, 0, 0, /* width and bbox (w,h,x,y) */
+ /*08c0:*/ 0xe0, /* ###..... */
+ /*08c1:*/ 0xe0, /* ###..... */
+ /*08c2:*/ 0x60, /* .##..... */
+ /*08c3:*/ 0x60, /* .##..... */
+ /*08c4:*/ 0x70, /* .###.... */
+ /*08c5:*/ 0x30, /* ..##.... */
+ /*08c6:*/ 0x30, /* ..##.... */
+ /*08c7:*/ 0x38, /* ..###... */
+ /*08c8:*/ 0x38, /* ..###... */
+ /*08c9:*/ 0x18, /* ...##... */
+ /*08ca:*/ 0x18, /* ...##... */
+ /*08cb:*/ 0x1c, /* ...###.. */
+ /*08cc:*/ 0x0c, /* ....##.. */
+ /*08cd:*/ 0x0c, /* ....##.. */
+ /*08ce:*/ 0x0e, /* ....###. */
+ /*08cf:*/ 0x06, /* .....##. */
+ /*08d0:*/ 0x06, /* .....##. */
+ /*08d1:*/ 0x07, /* .....### */
+ /*08d2:*/ 0x07, /* .....### */
+/* --- new character bracketright (93) starting at offset 0x08d3 --- */
+ /*08d3:*/ 8, 5, 24, 2, -5, /* width and bbox (w,h,x,y) */
+ /*08d8:*/ 0xf8, /* #####... */
+ /*08d9:*/ 0xf8, /* #####... */
+ /*08da:*/ 0x38, /* ..###... */
+ /*08db:*/ 0x38, /* ..###... */
+ /*08dc:*/ 0x38, /* ..###... */
+ /*08dd:*/ 0x38, /* ..###... */
+ /*08de:*/ 0x38, /* ..###... */
+ /*08df:*/ 0x38, /* ..###... */
+ /*08e0:*/ 0x38, /* ..###... */
+ /*08e1:*/ 0x38, /* ..###... */
+ /*08e2:*/ 0x38, /* ..###... */
+ /*08e3:*/ 0x38, /* ..###... */
+ /*08e4:*/ 0x38, /* ..###... */
+ /*08e5:*/ 0x38, /* ..###... */
+ /*08e6:*/ 0x38, /* ..###... */
+ /*08e7:*/ 0x38, /* ..###... */
+ /*08e8:*/ 0x38, /* ..###... */
+ /*08e9:*/ 0x38, /* ..###... */
+ /*08ea:*/ 0x38, /* ..###... */
+ /*08eb:*/ 0x38, /* ..###... */
+ /*08ec:*/ 0x38, /* ..###... */
+ /*08ed:*/ 0x38, /* ..###... */
+ /*08ee:*/ 0xf8, /* #####... */
+ /*08ef:*/ 0xf8, /* #####... */
+/* --- new character asciicircum (94) starting at offset 0x08f0 --- */
+ /*08f0:*/ 14, 11, 9, 1, 10, /* width and bbox (w,h,x,y) */
+ /*08f5:*/ 0x0e,0x00, /* ....###......... */
+ /*08f7:*/ 0x0e,0x00, /* ....###......... */
+ /*08f9:*/ 0x1f,0x00, /* ...#####........ */
+ /*08fb:*/ 0x1b,0x00, /* ...##.##........ */
+ /*08fd:*/ 0x3b,0x80, /* ..###.###....... */
+ /*08ff:*/ 0x71,0xc0, /* .###...###...... */
+ /*0901:*/ 0x71,0xc0, /* .###...###...... */
+ /*0903:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0905:*/ 0xe0,0xe0, /* ###.....###..... */
+/* --- new character underscore (95) starting at offset 0x0907 --- */
+ /*0907:*/ 14, 14, 2, 0, -5, /* width and bbox (w,h,x,y) */
+ /*090c:*/ 0xff,0xfc, /* ##############.. */
+ /*090e:*/ 0xff,0xfc, /* ##############.. */
+/* --- new character grave (96) starting at offset 0x0910 --- */
+ /*0910:*/ 8, 6, 4, 1, 15, /* width and bbox (w,h,x,y) */
+ /*0915:*/ 0xe0, /* ###..... */
+ /*0916:*/ 0x70, /* .###.... */
+ /*0917:*/ 0x38, /* ..###... */
+ /*0918:*/ 0x1c, /* ...###.. */
+/* --- new character a (97) starting at offset 0x0919 --- */
+ /*0919:*/ 14, 12, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*091e:*/ 0x1f,0x80, /* ...######....... */
+ /*0920:*/ 0x3f,0xc0, /* ..########...... */
+ /*0922:*/ 0x71,0xe0, /* .###...####..... */
+ /*0924:*/ 0x70,0xe0, /* .###....###..... */
+ /*0926:*/ 0x00,0xe0, /* ........###..... */
+ /*0928:*/ 0x07,0xe0, /* .....######..... */
+ /*092a:*/ 0x3f,0xe0, /* ..#########..... */
+ /*092c:*/ 0x7c,0xe0, /* .#####..###..... */
+ /*092e:*/ 0xf0,0xe0, /* ####....###..... */
+ /*0930:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0932:*/ 0xe1,0xe0, /* ###....####..... */
+ /*0934:*/ 0xf3,0xe0, /* ####..#####..... */
+ /*0936:*/ 0x7f,0xf0, /* .###########.... */
+ /*0938:*/ 0x3e,0x70, /* ..#####..###.... */
+/* --- new character b (98) starting at offset 0x093a --- */
+ /*093a:*/ 15, 12, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*093f:*/ 0xe0,0x00, /* ###............. */
+ /*0941:*/ 0xe0,0x00, /* ###............. */
+ /*0943:*/ 0xe0,0x00, /* ###............. */
+ /*0945:*/ 0xe0,0x00, /* ###............. */
+ /*0947:*/ 0xe0,0x00, /* ###............. */
+ /*0949:*/ 0xef,0x80, /* ###.#####....... */
+ /*094b:*/ 0xff,0xc0, /* ##########...... */
+ /*094d:*/ 0xf9,0xe0, /* #####..####..... */
+ /*094f:*/ 0xf0,0xe0, /* ####....###..... */
+ /*0951:*/ 0xe0,0x70, /* ###......###.... */
+ /*0953:*/ 0xe0,0x70, /* ###......###.... */
+ /*0955:*/ 0xe0,0x70, /* ###......###.... */
+ /*0957:*/ 0xe0,0x70, /* ###......###.... */
+ /*0959:*/ 0xe0,0x70, /* ###......###.... */
+ /*095b:*/ 0xe0,0x70, /* ###......###.... */
+ /*095d:*/ 0xf0,0xe0, /* ####....###..... */
+ /*095f:*/ 0xf9,0xe0, /* #####..####..... */
+ /*0961:*/ 0xff,0xc0, /* ##########...... */
+ /*0963:*/ 0xef,0x80, /* ###.#####....... */
+/* --- new character c (99) starting at offset 0x0965 --- */
+ /*0965:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*096a:*/ 0x1f,0x80, /* ...######....... */
+ /*096c:*/ 0x3f,0xc0, /* ..########...... */
+ /*096e:*/ 0x79,0xe0, /* .####..####..... */
+ /*0970:*/ 0x70,0xe0, /* .###....###..... */
+ /*0972:*/ 0xe0,0x00, /* ###............. */
+ /*0974:*/ 0xe0,0x00, /* ###............. */
+ /*0976:*/ 0xe0,0x00, /* ###............. */
+ /*0978:*/ 0xe0,0x00, /* ###............. */
+ /*097a:*/ 0xe0,0x00, /* ###............. */
+ /*097c:*/ 0xe0,0x00, /* ###............. */
+ /*097e:*/ 0x70,0xe0, /* .###....###..... */
+ /*0980:*/ 0x79,0xe0, /* .####..####..... */
+ /*0982:*/ 0x3f,0xc0, /* ..########...... */
+ /*0984:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character d (100) starting at offset 0x0986 --- */
+ /*0986:*/ 15, 12, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*098b:*/ 0x00,0x70, /* .........###.... */
+ /*098d:*/ 0x00,0x70, /* .........###.... */
+ /*098f:*/ 0x00,0x70, /* .........###.... */
+ /*0991:*/ 0x00,0x70, /* .........###.... */
+ /*0993:*/ 0x00,0x70, /* .........###.... */
+ /*0995:*/ 0x1f,0x70, /* ...#####.###.... */
+ /*0997:*/ 0x3f,0xf0, /* ..##########.... */
+ /*0999:*/ 0x79,0xf0, /* .####..#####.... */
+ /*099b:*/ 0x70,0xf0, /* .###....####.... */
+ /*099d:*/ 0xe0,0x70, /* ###......###.... */
+ /*099f:*/ 0xe0,0x70, /* ###......###.... */
+ /*09a1:*/ 0xe0,0x70, /* ###......###.... */
+ /*09a3:*/ 0xe0,0x70, /* ###......###.... */
+ /*09a5:*/ 0xe0,0x70, /* ###......###.... */
+ /*09a7:*/ 0xe0,0x70, /* ###......###.... */
+ /*09a9:*/ 0x70,0xf0, /* .###....####.... */
+ /*09ab:*/ 0x79,0xf0, /* .####..#####.... */
+ /*09ad:*/ 0x3f,0xf0, /* ..##########.... */
+ /*09af:*/ 0x1f,0x70, /* ...#####.###.... */
+/* --- new character e (101) starting at offset 0x09b1 --- */
+ /*09b1:*/ 14, 12, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*09b6:*/ 0x0f,0x00, /* ....####........ */
+ /*09b8:*/ 0x3f,0xc0, /* ..########...... */
+ /*09ba:*/ 0x79,0xe0, /* .####..####..... */
+ /*09bc:*/ 0x70,0xe0, /* .###....###..... */
+ /*09be:*/ 0xe0,0x70, /* ###......###.... */
+ /*09c0:*/ 0xe0,0x70, /* ###......###.... */
+ /*09c2:*/ 0xff,0xf0, /* ############.... */
+ /*09c4:*/ 0xff,0xf0, /* ############.... */
+ /*09c6:*/ 0xe0,0x00, /* ###............. */
+ /*09c8:*/ 0xe0,0x00, /* ###............. */
+ /*09ca:*/ 0x70,0x70, /* .###.....###.... */
+ /*09cc:*/ 0x78,0xf0, /* .####...####.... */
+ /*09ce:*/ 0x3f,0xe0, /* ..#########..... */
+ /*09d0:*/ 0x0f,0x80, /* ....#####....... */
+/* --- new character f (102) starting at offset 0x09d2 --- */
+ /*09d2:*/ 9, 7, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*09d7:*/ 0x1e, /* ...####. */
+ /*09d8:*/ 0x3e, /* ..#####. */
+ /*09d9:*/ 0x38, /* ..###... */
+ /*09da:*/ 0x38, /* ..###... */
+ /*09db:*/ 0x38, /* ..###... */
+ /*09dc:*/ 0xfe, /* #######. */
+ /*09dd:*/ 0xfe, /* #######. */
+ /*09de:*/ 0x38, /* ..###... */
+ /*09df:*/ 0x38, /* ..###... */
+ /*09e0:*/ 0x38, /* ..###... */
+ /*09e1:*/ 0x38, /* ..###... */
+ /*09e2:*/ 0x38, /* ..###... */
+ /*09e3:*/ 0x38, /* ..###... */
+ /*09e4:*/ 0x38, /* ..###... */
+ /*09e5:*/ 0x38, /* ..###... */
+ /*09e6:*/ 0x38, /* ..###... */
+ /*09e7:*/ 0x38, /* ..###... */
+ /*09e8:*/ 0x38, /* ..###... */
+ /*09e9:*/ 0x38, /* ..###... */
+/* --- new character g (103) starting at offset 0x09ea --- */
+ /*09ea:*/ 15, 12, 19, 1, -5, /* width and bbox (w,h,x,y) */
+ /*09ef:*/ 0x1f,0x70, /* ...#####.###.... */
+ /*09f1:*/ 0x3f,0xf0, /* ..##########.... */
+ /*09f3:*/ 0x79,0xf0, /* .####..#####.... */
+ /*09f5:*/ 0x70,0xf0, /* .###....####.... */
+ /*09f7:*/ 0xe0,0x70, /* ###......###.... */
+ /*09f9:*/ 0xe0,0x70, /* ###......###.... */
+ /*09fb:*/ 0xe0,0x70, /* ###......###.... */
+ /*09fd:*/ 0xe0,0x70, /* ###......###.... */
+ /*09ff:*/ 0xe0,0x70, /* ###......###.... */
+ /*0a01:*/ 0xe0,0x70, /* ###......###.... */
+ /*0a03:*/ 0x70,0xf0, /* .###....####.... */
+ /*0a05:*/ 0x79,0xf0, /* .####..#####.... */
+ /*0a07:*/ 0x3f,0xf0, /* ..##########.... */
+ /*0a09:*/ 0x1f,0x70, /* ...#####.###.... */
+ /*0a0b:*/ 0x00,0x70, /* .........###.... */
+ /*0a0d:*/ 0xe0,0x70, /* ###......###.... */
+ /*0a0f:*/ 0xf0,0xe0, /* ####....###..... */
+ /*0a11:*/ 0x7f,0xe0, /* .##########..... */
+ /*0a13:*/ 0x1f,0x80, /* ...######....... */
+/* --- new character h (104) starting at offset 0x0a15 --- */
+ /*0a15:*/ 15, 11, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a1a:*/ 0xe0,0x00, /* ###............. */
+ /*0a1c:*/ 0xe0,0x00, /* ###............. */
+ /*0a1e:*/ 0xe0,0x00, /* ###............. */
+ /*0a20:*/ 0xe0,0x00, /* ###............. */
+ /*0a22:*/ 0xe0,0x00, /* ###............. */
+ /*0a24:*/ 0xef,0x00, /* ###.####........ */
+ /*0a26:*/ 0xff,0xc0, /* ##########...... */
+ /*0a28:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0a2a:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a2c:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a2e:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a30:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a32:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a34:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a36:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a38:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a3a:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a3c:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0a3e:*/ 0xe0,0xe0, /* ###.....###..... */
+/* --- new character i (105) starting at offset 0x0a40 --- */
+ /*0a40:*/ 7, 3, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a45:*/ 0xe0, /* ###..... */
+ /*0a46:*/ 0xe0, /* ###..... */
+ /*0a47:*/ 0xe0, /* ###..... */
+ /*0a48:*/ 0x00, /* ........ */
+ /*0a49:*/ 0x00, /* ........ */
+ /*0a4a:*/ 0xe0, /* ###..... */
+ /*0a4b:*/ 0xe0, /* ###..... */
+ /*0a4c:*/ 0xe0, /* ###..... */
+ /*0a4d:*/ 0xe0, /* ###..... */
+ /*0a4e:*/ 0xe0, /* ###..... */
+ /*0a4f:*/ 0xe0, /* ###..... */
+ /*0a50:*/ 0xe0, /* ###..... */
+ /*0a51:*/ 0xe0, /* ###..... */
+ /*0a52:*/ 0xe0, /* ###..... */
+ /*0a53:*/ 0xe0, /* ###..... */
+ /*0a54:*/ 0xe0, /* ###..... */
+ /*0a55:*/ 0xe0, /* ###..... */
+ /*0a56:*/ 0xe0, /* ###..... */
+ /*0a57:*/ 0xe0, /* ###..... */
+/* --- new character j (106) starting at offset 0x0a58 --- */
+ /*0a58:*/ 7, 5, 24, 0, -5, /* width and bbox (w,h,x,y) */
+ /*0a5d:*/ 0x38, /* ..###... */
+ /*0a5e:*/ 0x38, /* ..###... */
+ /*0a5f:*/ 0x38, /* ..###... */
+ /*0a60:*/ 0x00, /* ........ */
+ /*0a61:*/ 0x00, /* ........ */
+ /*0a62:*/ 0x38, /* ..###... */
+ /*0a63:*/ 0x38, /* ..###... */
+ /*0a64:*/ 0x38, /* ..###... */
+ /*0a65:*/ 0x38, /* ..###... */
+ /*0a66:*/ 0x38, /* ..###... */
+ /*0a67:*/ 0x38, /* ..###... */
+ /*0a68:*/ 0x38, /* ..###... */
+ /*0a69:*/ 0x38, /* ..###... */
+ /*0a6a:*/ 0x38, /* ..###... */
+ /*0a6b:*/ 0x38, /* ..###... */
+ /*0a6c:*/ 0x38, /* ..###... */
+ /*0a6d:*/ 0x38, /* ..###... */
+ /*0a6e:*/ 0x38, /* ..###... */
+ /*0a6f:*/ 0x38, /* ..###... */
+ /*0a70:*/ 0x38, /* ..###... */
+ /*0a71:*/ 0x38, /* ..###... */
+ /*0a72:*/ 0x38, /* ..###... */
+ /*0a73:*/ 0xf8, /* #####... */
+ /*0a74:*/ 0xf0, /* ####.... */
+/* --- new character k (107) starting at offset 0x0a75 --- */
+ /*0a75:*/ 14, 12, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a7a:*/ 0xe0,0x00, /* ###............. */
+ /*0a7c:*/ 0xe0,0x00, /* ###............. */
+ /*0a7e:*/ 0xe0,0x00, /* ###............. */
+ /*0a80:*/ 0xe0,0x00, /* ###............. */
+ /*0a82:*/ 0xe0,0x00, /* ###............. */
+ /*0a84:*/ 0xe1,0xe0, /* ###....####..... */
+ /*0a86:*/ 0xe3,0xc0, /* ###...####...... */
+ /*0a88:*/ 0xe7,0x80, /* ###..####....... */
+ /*0a8a:*/ 0xef,0x00, /* ###.####........ */
+ /*0a8c:*/ 0xfe,0x00, /* #######......... */
+ /*0a8e:*/ 0xfc,0x00, /* ######.......... */
+ /*0a90:*/ 0xfe,0x00, /* #######......... */
+ /*0a92:*/ 0xef,0x00, /* ###.####........ */
+ /*0a94:*/ 0xe7,0x00, /* ###..###........ */
+ /*0a96:*/ 0xe7,0x80, /* ###..####....... */
+ /*0a98:*/ 0xe3,0xc0, /* ###...####...... */
+ /*0a9a:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0a9c:*/ 0xe1,0xe0, /* ###....####..... */
+ /*0a9e:*/ 0xe0,0xf0, /* ###.....####.... */
+/* --- new character l (108) starting at offset 0x0aa0 --- */
+ /*0aa0:*/ 7, 3, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0aa5:*/ 0xe0, /* ###..... */
+ /*0aa6:*/ 0xe0, /* ###..... */
+ /*0aa7:*/ 0xe0, /* ###..... */
+ /*0aa8:*/ 0xe0, /* ###..... */
+ /*0aa9:*/ 0xe0, /* ###..... */
+ /*0aaa:*/ 0xe0, /* ###..... */
+ /*0aab:*/ 0xe0, /* ###..... */
+ /*0aac:*/ 0xe0, /* ###..... */
+ /*0aad:*/ 0xe0, /* ###..... */
+ /*0aae:*/ 0xe0, /* ###..... */
+ /*0aaf:*/ 0xe0, /* ###..... */
+ /*0ab0:*/ 0xe0, /* ###..... */
+ /*0ab1:*/ 0xe0, /* ###..... */
+ /*0ab2:*/ 0xe0, /* ###..... */
+ /*0ab3:*/ 0xe0, /* ###..... */
+ /*0ab4:*/ 0xe0, /* ###..... */
+ /*0ab5:*/ 0xe0, /* ###..... */
+ /*0ab6:*/ 0xe0, /* ###..... */
+ /*0ab7:*/ 0xe0, /* ###..... */
+/* --- new character m (109) starting at offset 0x0ab8 --- */
+ /*0ab8:*/ 21, 17, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0abd:*/ 0xef,0x3e,0x00, /* ###.####..#####......... */
+ /*0ac0:*/ 0xff,0xff,0x00, /* ################........ */
+ /*0ac3:*/ 0xf3,0xe7,0x80, /* ####..#####..####....... */
+ /*0ac6:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ac9:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0acc:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0acf:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ad2:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ad5:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ad8:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0adb:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ade:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ae1:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+ /*0ae4:*/ 0xe1,0xc3,0x80, /* ###....###....###....... */
+/* --- new character n (110) starting at offset 0x0ae7 --- */
+ /*0ae7:*/ 15, 11, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0aec:*/ 0xef,0x80, /* ###.#####....... */
+ /*0aee:*/ 0xff,0xc0, /* ##########...... */
+ /*0af0:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0af2:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0af4:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0af6:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0af8:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0afa:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0afc:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0afe:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0b00:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0b02:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0b04:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0b06:*/ 0xe0,0xe0, /* ###.....###..... */
+/* --- new character o (111) starting at offset 0x0b08 --- */
+ /*0b08:*/ 14, 12, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0b0d:*/ 0x0f,0x00, /* ....####........ */
+ /*0b0f:*/ 0x3f,0xc0, /* ..########...... */
+ /*0b11:*/ 0x79,0xe0, /* .####..####..... */
+ /*0b13:*/ 0x70,0xe0, /* .###....###..... */
+ /*0b15:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b17:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b19:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b1b:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b1d:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b1f:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b21:*/ 0x70,0xe0, /* .###....###..... */
+ /*0b23:*/ 0x79,0xe0, /* .####..####..... */
+ /*0b25:*/ 0x3f,0xc0, /* ..########...... */
+ /*0b27:*/ 0x0f,0x00, /* ....####........ */
+/* --- new character p (112) starting at offset 0x0b29 --- */
+ /*0b29:*/ 15, 12, 19, 2, -5, /* width and bbox (w,h,x,y) */
+ /*0b2e:*/ 0xef,0x80, /* ###.#####....... */
+ /*0b30:*/ 0xff,0xc0, /* ##########...... */
+ /*0b32:*/ 0xf9,0xe0, /* #####..####..... */
+ /*0b34:*/ 0xf0,0xe0, /* ####....###..... */
+ /*0b36:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b38:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b3a:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b3c:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b3e:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b40:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b42:*/ 0xf0,0xe0, /* ####....###..... */
+ /*0b44:*/ 0xf9,0xe0, /* #####..####..... */
+ /*0b46:*/ 0xff,0xc0, /* ##########...... */
+ /*0b48:*/ 0xef,0x80, /* ###.#####....... */
+ /*0b4a:*/ 0xe0,0x00, /* ###............. */
+ /*0b4c:*/ 0xe0,0x00, /* ###............. */
+ /*0b4e:*/ 0xe0,0x00, /* ###............. */
+ /*0b50:*/ 0xe0,0x00, /* ###............. */
+ /*0b52:*/ 0xe0,0x00, /* ###............. */
+/* --- new character q (113) starting at offset 0x0b54 --- */
+ /*0b54:*/ 15, 12, 19, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0b59:*/ 0x1f,0x70, /* ...#####.###.... */
+ /*0b5b:*/ 0x3f,0xf0, /* ..##########.... */
+ /*0b5d:*/ 0x79,0xf0, /* .####..#####.... */
+ /*0b5f:*/ 0x70,0xf0, /* .###....####.... */
+ /*0b61:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b63:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b65:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b67:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b69:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b6b:*/ 0xe0,0x70, /* ###......###.... */
+ /*0b6d:*/ 0x70,0xf0, /* .###....####.... */
+ /*0b6f:*/ 0x79,0xf0, /* .####..#####.... */
+ /*0b71:*/ 0x3f,0xf0, /* ..##########.... */
+ /*0b73:*/ 0x1f,0x70, /* ...#####.###.... */
+ /*0b75:*/ 0x00,0x70, /* .........###.... */
+ /*0b77:*/ 0x00,0x70, /* .........###.... */
+ /*0b79:*/ 0x00,0x70, /* .........###.... */
+ /*0b7b:*/ 0x00,0x70, /* .........###.... */
+ /*0b7d:*/ 0x00,0x70, /* .........###.... */
+/* --- new character r (114) starting at offset 0x0b7f --- */
+ /*0b7f:*/ 10, 7, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0b84:*/ 0xe6, /* ###..##. */
+ /*0b85:*/ 0xee, /* ###.###. */
+ /*0b86:*/ 0xfe, /* #######. */
+ /*0b87:*/ 0xf0, /* ####.... */
+ /*0b88:*/ 0xe0, /* ###..... */
+ /*0b89:*/ 0xe0, /* ###..... */
+ /*0b8a:*/ 0xe0, /* ###..... */
+ /*0b8b:*/ 0xe0, /* ###..... */
+ /*0b8c:*/ 0xe0, /* ###..... */
+ /*0b8d:*/ 0xe0, /* ###..... */
+ /*0b8e:*/ 0xe0, /* ###..... */
+ /*0b8f:*/ 0xe0, /* ###..... */
+ /*0b90:*/ 0xe0, /* ###..... */
+ /*0b91:*/ 0xe0, /* ###..... */
+/* --- new character s (115) starting at offset 0x0b92 --- */
+ /*0b92:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0b97:*/ 0x3f,0x00, /* ..######........ */
+ /*0b99:*/ 0x7f,0x80, /* .########....... */
+ /*0b9b:*/ 0xf3,0xc0, /* ####..####...... */
+ /*0b9d:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0b9f:*/ 0xe0,0x00, /* ###............. */
+ /*0ba1:*/ 0xfc,0x00, /* ######.......... */
+ /*0ba3:*/ 0x7f,0x80, /* .########....... */
+ /*0ba5:*/ 0x0f,0xc0, /* ....######...... */
+ /*0ba7:*/ 0x01,0xe0, /* .......####..... */
+ /*0ba9:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bab:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bad:*/ 0xf1,0xe0, /* ####...####..... */
+ /*0baf:*/ 0x7f,0xc0, /* .#########...... */
+ /*0bb1:*/ 0x3f,0x80, /* ..#######....... */
+/* --- new character t (116) starting at offset 0x0bb3 --- */
+ /*0bb3:*/ 9, 7, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0bb8:*/ 0x38, /* ..###... */
+ /*0bb9:*/ 0x38, /* ..###... */
+ /*0bba:*/ 0x38, /* ..###... */
+ /*0bbb:*/ 0x38, /* ..###... */
+ /*0bbc:*/ 0xfe, /* #######. */
+ /*0bbd:*/ 0xfe, /* #######. */
+ /*0bbe:*/ 0x38, /* ..###... */
+ /*0bbf:*/ 0x38, /* ..###... */
+ /*0bc0:*/ 0x38, /* ..###... */
+ /*0bc1:*/ 0x38, /* ..###... */
+ /*0bc2:*/ 0x38, /* ..###... */
+ /*0bc3:*/ 0x38, /* ..###... */
+ /*0bc4:*/ 0x38, /* ..###... */
+ /*0bc5:*/ 0x38, /* ..###... */
+ /*0bc6:*/ 0x38, /* ..###... */
+ /*0bc7:*/ 0x38, /* ..###... */
+ /*0bc8:*/ 0x3e, /* ..#####. */
+ /*0bc9:*/ 0x1e, /* ...####. */
+/* --- new character u (117) starting at offset 0x0bca --- */
+ /*0bca:*/ 15, 11, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0bcf:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bd1:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bd3:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bd5:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bd7:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bd9:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bdb:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bdd:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0bdf:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0be1:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0be3:*/ 0xe1,0xe0, /* ###....####..... */
+ /*0be5:*/ 0x73,0xe0, /* .###..#####..... */
+ /*0be7:*/ 0x7e,0xe0, /* .######.###..... */
+ /*0be9:*/ 0x1c,0xe0, /* ...###..###..... */
+/* --- new character v (118) starting at offset 0x0beb --- */
+ /*0beb:*/ 14, 12, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0bf0:*/ 0xe0,0x70, /* ###......###.... */
+ /*0bf2:*/ 0xe0,0x70, /* ###......###.... */
+ /*0bf4:*/ 0xe0,0x70, /* ###......###.... */
+ /*0bf6:*/ 0x70,0xe0, /* .###....###..... */
+ /*0bf8:*/ 0x70,0xe0, /* .###....###..... */
+ /*0bfa:*/ 0x70,0xe0, /* .###....###..... */
+ /*0bfc:*/ 0x39,0xc0, /* ..###..###...... */
+ /*0bfe:*/ 0x39,0xc0, /* ..###..###...... */
+ /*0c00:*/ 0x39,0xc0, /* ..###..###...... */
+ /*0c02:*/ 0x1f,0x80, /* ...######....... */
+ /*0c04:*/ 0x1f,0x80, /* ...######....... */
+ /*0c06:*/ 0x0f,0x00, /* ....####........ */
+ /*0c08:*/ 0x0f,0x00, /* ....####........ */
+ /*0c0a:*/ 0x0f,0x00, /* ....####........ */
+/* --- new character w (119) starting at offset 0x0c0c --- */
+ /*0c0c:*/ 19, 19, 14, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0c11:*/ 0xe0,0xe0,0xe0, /* ###.....###.....###..... */
+ /*0c14:*/ 0xe0,0xe0,0xe0, /* ###.....###.....###..... */
+ /*0c17:*/ 0x60,0xe0,0xc0, /* .##.....###.....##...... */
+ /*0c1a:*/ 0x71,0xf1,0xc0, /* .###...#####...###...... */
+ /*0c1d:*/ 0x71,0xf1,0xc0, /* .###...#####...###...... */
+ /*0c20:*/ 0x31,0xb1,0x80, /* ..##...##.##...##....... */
+ /*0c23:*/ 0x33,0xb9,0x80, /* ..##..###.###..##....... */
+ /*0c26:*/ 0x3b,0xbb,0x80, /* ..###.###.###.###....... */
+ /*0c29:*/ 0x1b,0x1b,0x00, /* ...##.##...##.##........ */
+ /*0c2c:*/ 0x1f,0x1f,0x00, /* ...#####...#####........ */
+ /*0c2f:*/ 0x1f,0x1f,0x00, /* ...#####...#####........ */
+ /*0c32:*/ 0x0e,0x0e,0x00, /* ....###.....###......... */
+ /*0c35:*/ 0x0e,0x0e,0x00, /* ....###.....###......... */
+ /*0c38:*/ 0x0e,0x0e,0x00, /* ....###.....###......... */
+/* --- new character x (120) starting at offset 0x0c3b --- */
+ /*0c3b:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0c40:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*0c42:*/ 0xf1,0xe0, /* ####...####..... */
+ /*0c44:*/ 0x71,0xc0, /* .###...###...... */
+ /*0c46:*/ 0x3b,0x80, /* ..###.###....... */
+ /*0c48:*/ 0x3f,0x80, /* ..#######....... */
+ /*0c4a:*/ 0x1f,0x00, /* ...#####........ */
+ /*0c4c:*/ 0x0e,0x00, /* ....###......... */
+ /*0c4e:*/ 0x1f,0x00, /* ...#####........ */
+ /*0c50:*/ 0x1f,0x00, /* ...#####........ */
+ /*0c52:*/ 0x3b,0x80, /* ..###.###....... */
+ /*0c54:*/ 0x7b,0xc0, /* .####.####...... */
+ /*0c56:*/ 0x71,0xc0, /* .###...###...... */
+ /*0c58:*/ 0xf1,0xe0, /* ####...####..... */
+ /*0c5a:*/ 0xe0,0xe0, /* ###.....###..... */
+/* --- new character y (121) starting at offset 0x0c5c --- */
+ /*0c5c:*/ 15, 13, 19, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0c61:*/ 0xe0,0x38, /* ###.......###... */
+ /*0c63:*/ 0xe0,0x38, /* ###.......###... */
+ /*0c65:*/ 0x70,0x38, /* .###......###... */
+ /*0c67:*/ 0x78,0x70, /* .####....###.... */
+ /*0c69:*/ 0x38,0x70, /* ..###....###.... */
+ /*0c6b:*/ 0x3c,0xf0, /* ..####..####.... */
+ /*0c6d:*/ 0x1c,0xe0, /* ...###..###..... */
+ /*0c6f:*/ 0x1c,0xe0, /* ...###..###..... */
+ /*0c71:*/ 0x0f,0xc0, /* ....######...... */
+ /*0c73:*/ 0x0f,0xc0, /* ....######...... */
+ /*0c75:*/ 0x07,0xc0, /* .....#####...... */
+ /*0c77:*/ 0x07,0x80, /* .....####....... */
+ /*0c79:*/ 0x03,0x80, /* ......###....... */
+ /*0c7b:*/ 0x03,0x80, /* ......###....... */
+ /*0c7d:*/ 0x07,0x00, /* .....###........ */
+ /*0c7f:*/ 0x07,0x00, /* .....###........ */
+ /*0c81:*/ 0x0e,0x00, /* ....###......... */
+ /*0c83:*/ 0x3e,0x00, /* ..#####......... */
+ /*0c85:*/ 0x3c,0x00, /* ..####.......... */
+/* --- new character z (122) starting at offset 0x0c87 --- */
+ /*0c87:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0c8c:*/ 0xff,0xe0, /* ###########..... */
+ /*0c8e:*/ 0xff,0xe0, /* ###########..... */
+ /*0c90:*/ 0x01,0xc0, /* .......###...... */
+ /*0c92:*/ 0x03,0x80, /* ......###....... */
+ /*0c94:*/ 0x07,0x80, /* .....####....... */
+ /*0c96:*/ 0x0f,0x00, /* ....####........ */
+ /*0c98:*/ 0x0e,0x00, /* ....###......... */
+ /*0c9a:*/ 0x1e,0x00, /* ...####......... */
+ /*0c9c:*/ 0x3c,0x00, /* ..####.......... */
+ /*0c9e:*/ 0x38,0x00, /* ..###........... */
+ /*0ca0:*/ 0x70,0x00, /* .###............ */
+ /*0ca2:*/ 0xf0,0x00, /* ####............ */
+ /*0ca4:*/ 0xff,0xe0, /* ###########..... */
+ /*0ca6:*/ 0xff,0xe0, /* ###########..... */
+/* --- new character braceleft (123) starting at offset 0x0ca8 --- */
+ /*0ca8:*/ 10, 7, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0cad:*/ 0x0e, /* ....###. */
+ /*0cae:*/ 0x1c, /* ...###.. */
+ /*0caf:*/ 0x38, /* ..###... */
+ /*0cb0:*/ 0x38, /* ..###... */
+ /*0cb1:*/ 0x38, /* ..###... */
+ /*0cb2:*/ 0x38, /* ..###... */
+ /*0cb3:*/ 0x38, /* ..###... */
+ /*0cb4:*/ 0x38, /* ..###... */
+ /*0cb5:*/ 0x38, /* ..###... */
+ /*0cb6:*/ 0x38, /* ..###... */
+ /*0cb7:*/ 0x70, /* .###.... */
+ /*0cb8:*/ 0xe0, /* ###..... */
+ /*0cb9:*/ 0xe0, /* ###..... */
+ /*0cba:*/ 0x70, /* .###.... */
+ /*0cbb:*/ 0x38, /* ..###... */
+ /*0cbc:*/ 0x38, /* ..###... */
+ /*0cbd:*/ 0x38, /* ..###... */
+ /*0cbe:*/ 0x38, /* ..###... */
+ /*0cbf:*/ 0x38, /* ..###... */
+ /*0cc0:*/ 0x38, /* ..###... */
+ /*0cc1:*/ 0x38, /* ..###... */
+ /*0cc2:*/ 0x38, /* ..###... */
+ /*0cc3:*/ 0x1c, /* ...###.. */
+ /*0cc4:*/ 0x0e, /* ....###. */
+/* --- new character bar (124) starting at offset 0x0cc5 --- */
+ /*0cc5:*/ 7, 3, 24, 2, -5, /* width and bbox (w,h,x,y) */
+ /*0cca:*/ 0xe0, /* ###..... */
+ /*0ccb:*/ 0xe0, /* ###..... */
+ /*0ccc:*/ 0xe0, /* ###..... */
+ /*0ccd:*/ 0xe0, /* ###..... */
+ /*0cce:*/ 0xe0, /* ###..... */
+ /*0ccf:*/ 0xe0, /* ###..... */
+ /*0cd0:*/ 0xe0, /* ###..... */
+ /*0cd1:*/ 0xe0, /* ###..... */
+ /*0cd2:*/ 0xe0, /* ###..... */
+ /*0cd3:*/ 0xe0, /* ###..... */
+ /*0cd4:*/ 0xe0, /* ###..... */
+ /*0cd5:*/ 0xe0, /* ###..... */
+ /*0cd6:*/ 0xe0, /* ###..... */
+ /*0cd7:*/ 0xe0, /* ###..... */
+ /*0cd8:*/ 0xe0, /* ###..... */
+ /*0cd9:*/ 0xe0, /* ###..... */
+ /*0cda:*/ 0xe0, /* ###..... */
+ /*0cdb:*/ 0xe0, /* ###..... */
+ /*0cdc:*/ 0xe0, /* ###..... */
+ /*0cdd:*/ 0xe0, /* ###..... */
+ /*0cde:*/ 0xe0, /* ###..... */
+ /*0cdf:*/ 0xe0, /* ###..... */
+ /*0ce0:*/ 0xe0, /* ###..... */
+ /*0ce1:*/ 0xe0, /* ###..... */
+/* --- new character braceright (125) starting at offset 0x0ce2 --- */
+ /*0ce2:*/ 10, 7, 24, 2, -5, /* width and bbox (w,h,x,y) */
+ /*0ce7:*/ 0xe0, /* ###..... */
+ /*0ce8:*/ 0x70, /* .###.... */
+ /*0ce9:*/ 0x38, /* ..###... */
+ /*0cea:*/ 0x38, /* ..###... */
+ /*0ceb:*/ 0x38, /* ..###... */
+ /*0cec:*/ 0x38, /* ..###... */
+ /*0ced:*/ 0x38, /* ..###... */
+ /*0cee:*/ 0x38, /* ..###... */
+ /*0cef:*/ 0x38, /* ..###... */
+ /*0cf0:*/ 0x38, /* ..###... */
+ /*0cf1:*/ 0x1c, /* ...###.. */
+ /*0cf2:*/ 0x0e, /* ....###. */
+ /*0cf3:*/ 0x0e, /* ....###. */
+ /*0cf4:*/ 0x1c, /* ...###.. */
+ /*0cf5:*/ 0x38, /* ..###... */
+ /*0cf6:*/ 0x38, /* ..###... */
+ /*0cf7:*/ 0x38, /* ..###... */
+ /*0cf8:*/ 0x38, /* ..###... */
+ /*0cf9:*/ 0x38, /* ..###... */
+ /*0cfa:*/ 0x38, /* ..###... */
+ /*0cfb:*/ 0x38, /* ..###... */
+ /*0cfc:*/ 0x38, /* ..###... */
+ /*0cfd:*/ 0x70, /* .###.... */
+ /*0cfe:*/ 0xe0, /* ###..... */
+/* --- new character asciitilde (126) starting at offset 0x0cff --- */
+ /*0cff:*/ 14, 11, 4, 1, 5, /* width and bbox (w,h,x,y) */
+ /*0d04:*/ 0x78,0xe0, /* .####...###..... */
+ /*0d06:*/ 0xfe,0xe0, /* #######.###..... */
+ /*0d08:*/ 0xef,0xe0, /* ###.#######..... */
+ /*0d0a:*/ 0xe3,0xc0, /* ###...####...... */
+};
+static const uint16_t font_helvB24_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x001e /* quotedbl */,
+ 0x0029 /* numbersign */,
+ 0x0052 /* dollar */,
+ 0x0081 /* percent */,
+ 0x00bc /* ampersand */,
+ 0x00e5 /* quotesingle */,
+ 0x00f0 /* parenleft */,
+ 0x010d /* parenright */,
+ 0x012a /* asterisk */,
+ 0x0136 /* plus */,
+ 0x0153 /* comma */,
+ 0x015e /* hyphen */,
+ 0x0166 /* period */,
+ 0x016e /* slash */,
+ 0x0186 /* zero */,
+ 0x01af /* one */,
+ 0x01c6 /* two */,
+ 0x01ef /* three */,
+ 0x0218 /* four */,
+ 0x0241 /* five */,
+ 0x026a /* six */,
+ 0x0293 /* seven */,
+ 0x02bc /* eight */,
+ 0x02e5 /* nine */,
+ 0x030e /* colon */,
+ 0x0321 /* semicolon */,
+ 0x0337 /* less */,
+ 0x0354 /* equal */,
+ 0x0365 /* greater */,
+ 0x0382 /* question */,
+ 0x03ad /* at */,
+ 0x03f4 /* A */,
+ 0x041f /* B */,
+ 0x044a /* C */,
+ 0x0475 /* D */,
+ 0x04a0 /* E */,
+ 0x04cb /* F */,
+ 0x04f6 /* G */,
+ 0x0534 /* H */,
+ 0x055f /* I */,
+ 0x0577 /* J */,
+ 0x05a2 /* K */,
+ 0x05cd /* L */,
+ 0x05f8 /* M */,
+ 0x0636 /* N */,
+ 0x0661 /* O */,
+ 0x069f /* P */,
+ 0x06ca /* Q */,
+ 0x0708 /* R */,
+ 0x0733 /* S */,
+ 0x075e /* T */,
+ 0x0789 /* U */,
+ 0x07b4 /* V */,
+ 0x07df /* W */,
+ 0x081d /* X */,
+ 0x0848 /* Y */,
+ 0x0873 /* Z */,
+ 0x089e /* bracketleft */,
+ 0x08bb /* backslash */,
+ 0x08d3 /* bracketright */,
+ 0x08f0 /* asciicircum */,
+ 0x0907 /* underscore */,
+ 0x0910 /* grave */,
+ 0x0919 /* a */,
+ 0x093a /* b */,
+ 0x0965 /* c */,
+ 0x0986 /* d */,
+ 0x09b1 /* e */,
+ 0x09d2 /* f */,
+ 0x09ea /* g */,
+ 0x0a15 /* h */,
+ 0x0a40 /* i */,
+ 0x0a58 /* j */,
+ 0x0a75 /* k */,
+ 0x0aa0 /* l */,
+ 0x0ab8 /* m */,
+ 0x0ae7 /* n */,
+ 0x0b08 /* o */,
+ 0x0b29 /* p */,
+ 0x0b54 /* q */,
+ 0x0b7f /* r */,
+ 0x0b92 /* s */,
+ 0x0bb3 /* t */,
+ 0x0bca /* u */,
+ 0x0beb /* v */,
+ 0x0c0c /* w */,
+ 0x0c3b /* x */,
+ 0x0c5c /* y */,
+ 0x0c87 /* z */,
+ 0x0ca8 /* braceleft */,
+ 0x0cc5 /* bar */,
+ 0x0ce2 /* braceright */,
+ 0x0cff /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_helvB24 = {
+ .height = 27,
+ .ascent = 22,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_helvB24_data,
+ .charoffs = font_helvB24_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/helvR08.c b/Src/osmolib/src/target/firmware/fb/helvR08.c
new file mode 100644
index 0000000..7ebf82e
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/helvR08.c
@@ -0,0 +1,826 @@
+#include <fb/font.h>
+static const uint8_t font_helvR08_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 2, 1, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 2, 1, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0x80, /* #....... */
+ /*000c:*/ 0x80, /* #....... */
+ /*000d:*/ 0x80, /* #....... */
+ /*000e:*/ 0x80, /* #....... */
+ /*000f:*/ 0x00, /* ........ */
+ /*0010:*/ 0x80, /* #....... */
+/* --- new character quotedbl (34) starting at offset 0x0011 --- */
+ /*0011:*/ 3, 3, 3, 1, 3, /* width and bbox (w,h,x,y) */
+ /*0016:*/ 0xa0, /* #.#..... */
+ /*0017:*/ 0xa0, /* #.#..... */
+ /*0018:*/ 0xa0, /* #.#..... */
+/* --- new character numbersign (35) starting at offset 0x0019 --- */
+ /*0019:*/ 5, 5, 5, 0, 0, /* width and bbox (w,h,x,y) */
+ /*001e:*/ 0x50, /* .#.#.... */
+ /*001f:*/ 0xf8, /* #####... */
+ /*0020:*/ 0x50, /* .#.#.... */
+ /*0021:*/ 0xf8, /* #####... */
+ /*0022:*/ 0x50, /* .#.#.... */
+/* --- new character dollar (36) starting at offset 0x0023 --- */
+ /*0023:*/ 5, 4, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*0028:*/ 0x20, /* ..#..... */
+ /*0029:*/ 0x70, /* .###.... */
+ /*002a:*/ 0x80, /* #....... */
+ /*002b:*/ 0x60, /* .##..... */
+ /*002c:*/ 0x10, /* ...#.... */
+ /*002d:*/ 0xe0, /* ###..... */
+ /*002e:*/ 0x40, /* .#...... */
+/* --- new character percent (37) starting at offset 0x002f --- */
+ /*002f:*/ 7, 6, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0034:*/ 0xe8, /* ###.#... */
+ /*0035:*/ 0xa8, /* #.#.#... */
+ /*0036:*/ 0xd0, /* ##.#.... */
+ /*0037:*/ 0x2c, /* ..#.##.. */
+ /*0038:*/ 0x54, /* .#.#.#.. */
+ /*0039:*/ 0x5c, /* .#.###.. */
+/* --- new character ampersand (38) starting at offset 0x003a --- */
+ /*003a:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*003f:*/ 0x40, /* .#...... */
+ /*0040:*/ 0xa0, /* #.#..... */
+ /*0041:*/ 0x48, /* .#..#... */
+ /*0042:*/ 0xa8, /* #.#.#... */
+ /*0043:*/ 0xb0, /* #.##.... */
+ /*0044:*/ 0x58, /* .#.##... */
+/* --- new character quotesingle (39) starting at offset 0x0045 --- */
+ /*0045:*/ 2, 1, 2, 0, 6, /* width and bbox (w,h,x,y) */
+ /*004a:*/ 0x80, /* #....... */
+ /*004b:*/ 0x80, /* #....... */
+/* --- new character parenleft (40) starting at offset 0x004c --- */
+ /*004c:*/ 3, 2, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*0051:*/ 0x40, /* .#...... */
+ /*0052:*/ 0x80, /* #....... */
+ /*0053:*/ 0x80, /* #....... */
+ /*0054:*/ 0x80, /* #....... */
+ /*0055:*/ 0x80, /* #....... */
+ /*0056:*/ 0x80, /* #....... */
+ /*0057:*/ 0x40, /* .#...... */
+/* --- new character parenright (41) starting at offset 0x0058 --- */
+ /*0058:*/ 3, 2, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*005d:*/ 0x80, /* #....... */
+ /*005e:*/ 0x40, /* .#...... */
+ /*005f:*/ 0x40, /* .#...... */
+ /*0060:*/ 0x40, /* .#...... */
+ /*0061:*/ 0x40, /* .#...... */
+ /*0062:*/ 0x40, /* .#...... */
+ /*0063:*/ 0x80, /* #....... */
+/* --- new character asterisk (42) starting at offset 0x0064 --- */
+ /*0064:*/ 3, 3, 3, 1, 2, /* width and bbox (w,h,x,y) */
+ /*0069:*/ 0x40, /* .#...... */
+ /*006a:*/ 0xe0, /* ###..... */
+ /*006b:*/ 0x40, /* .#...... */
+/* --- new character plus (43) starting at offset 0x006c --- */
+ /*006c:*/ 5, 5, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0071:*/ 0x20, /* ..#..... */
+ /*0072:*/ 0x20, /* ..#..... */
+ /*0073:*/ 0xf8, /* #####... */
+ /*0074:*/ 0x20, /* ..#..... */
+ /*0075:*/ 0x20, /* ..#..... */
+/* --- new character comma (44) starting at offset 0x0076 --- */
+ /*0076:*/ 2, 2, 3, 0, -2, /* width and bbox (w,h,x,y) */
+ /*007b:*/ 0x40, /* .#...... */
+ /*007c:*/ 0x40, /* .#...... */
+ /*007d:*/ 0x80, /* #....... */
+/* --- new character hyphen (45) starting at offset 0x007e --- */
+ /*007e:*/ 3, 2, 1, 0, 2, /* width and bbox (w,h,x,y) */
+ /*0083:*/ 0xc0, /* ##...... */
+/* --- new character period (46) starting at offset 0x0084 --- */
+ /*0084:*/ 2, 1, 1, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0089:*/ 0x80, /* #....... */
+/* --- new character slash (47) starting at offset 0x008a --- */
+ /*008a:*/ 2, 2, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*008f:*/ 0x40, /* .#...... */
+ /*0090:*/ 0x40, /* .#...... */
+ /*0091:*/ 0x40, /* .#...... */
+ /*0092:*/ 0x80, /* #....... */
+ /*0093:*/ 0x80, /* #....... */
+ /*0094:*/ 0x80, /* #....... */
+ /*0095:*/ 0x80, /* #....... */
+/* --- new character zero (48) starting at offset 0x0096 --- */
+ /*0096:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*009b:*/ 0x60, /* .##..... */
+ /*009c:*/ 0x90, /* #..#.... */
+ /*009d:*/ 0x90, /* #..#.... */
+ /*009e:*/ 0x90, /* #..#.... */
+ /*009f:*/ 0x90, /* #..#.... */
+ /*00a0:*/ 0x60, /* .##..... */
+/* --- new character one (49) starting at offset 0x00a1 --- */
+ /*00a1:*/ 5, 2, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*00a6:*/ 0x40, /* .#...... */
+ /*00a7:*/ 0xc0, /* ##...... */
+ /*00a8:*/ 0x40, /* .#...... */
+ /*00a9:*/ 0x40, /* .#...... */
+ /*00aa:*/ 0x40, /* .#...... */
+ /*00ab:*/ 0x40, /* .#...... */
+/* --- new character two (50) starting at offset 0x00ac --- */
+ /*00ac:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00b1:*/ 0x60, /* .##..... */
+ /*00b2:*/ 0x90, /* #..#.... */
+ /*00b3:*/ 0x10, /* ...#.... */
+ /*00b4:*/ 0x20, /* ..#..... */
+ /*00b5:*/ 0x40, /* .#...... */
+ /*00b6:*/ 0xf0, /* ####.... */
+/* --- new character three (51) starting at offset 0x00b7 --- */
+ /*00b7:*/ 5, 3, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*00bc:*/ 0xc0, /* ##...... */
+ /*00bd:*/ 0x20, /* ..#..... */
+ /*00be:*/ 0xc0, /* ##...... */
+ /*00bf:*/ 0x20, /* ..#..... */
+ /*00c0:*/ 0x20, /* ..#..... */
+ /*00c1:*/ 0xc0, /* ##...... */
+/* --- new character four (52) starting at offset 0x00c2 --- */
+ /*00c2:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00c7:*/ 0x20, /* ..#..... */
+ /*00c8:*/ 0x20, /* ..#..... */
+ /*00c9:*/ 0x60, /* .##..... */
+ /*00ca:*/ 0xf0, /* ####.... */
+ /*00cb:*/ 0x20, /* ..#..... */
+ /*00cc:*/ 0x20, /* ..#..... */
+/* --- new character five (53) starting at offset 0x00cd --- */
+ /*00cd:*/ 5, 3, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*00d2:*/ 0xe0, /* ###..... */
+ /*00d3:*/ 0x80, /* #....... */
+ /*00d4:*/ 0xc0, /* ##...... */
+ /*00d5:*/ 0x20, /* ..#..... */
+ /*00d6:*/ 0x20, /* ..#..... */
+ /*00d7:*/ 0xc0, /* ##...... */
+/* --- new character six (54) starting at offset 0x00d8 --- */
+ /*00d8:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00dd:*/ 0x70, /* .###.... */
+ /*00de:*/ 0x80, /* #....... */
+ /*00df:*/ 0xe0, /* ###..... */
+ /*00e0:*/ 0x90, /* #..#.... */
+ /*00e1:*/ 0x90, /* #..#.... */
+ /*00e2:*/ 0x60, /* .##..... */
+/* --- new character seven (55) starting at offset 0x00e3 --- */
+ /*00e3:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00e8:*/ 0xf0, /* ####.... */
+ /*00e9:*/ 0x10, /* ...#.... */
+ /*00ea:*/ 0x20, /* ..#..... */
+ /*00eb:*/ 0x40, /* .#...... */
+ /*00ec:*/ 0x40, /* .#...... */
+ /*00ed:*/ 0x40, /* .#...... */
+/* --- new character eight (56) starting at offset 0x00ee --- */
+ /*00ee:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00f3:*/ 0x60, /* .##..... */
+ /*00f4:*/ 0x90, /* #..#.... */
+ /*00f5:*/ 0x60, /* .##..... */
+ /*00f6:*/ 0x90, /* #..#.... */
+ /*00f7:*/ 0x90, /* #..#.... */
+ /*00f8:*/ 0x60, /* .##..... */
+/* --- new character nine (57) starting at offset 0x00f9 --- */
+ /*00f9:*/ 5, 4, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00fe:*/ 0x60, /* .##..... */
+ /*00ff:*/ 0x90, /* #..#.... */
+ /*0100:*/ 0x90, /* #..#.... */
+ /*0101:*/ 0x70, /* .###.... */
+ /*0102:*/ 0x10, /* ...#.... */
+ /*0103:*/ 0x60, /* .##..... */
+/* --- new character colon (58) starting at offset 0x0104 --- */
+ /*0104:*/ 2, 1, 4, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0109:*/ 0x80, /* #....... */
+ /*010a:*/ 0x00, /* ........ */
+ /*010b:*/ 0x00, /* ........ */
+ /*010c:*/ 0x80, /* #....... */
+/* --- new character semicolon (59) starting at offset 0x010d --- */
+ /*010d:*/ 2, 2, 6, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0112:*/ 0x40, /* .#...... */
+ /*0113:*/ 0x00, /* ........ */
+ /*0114:*/ 0x00, /* ........ */
+ /*0115:*/ 0x40, /* .#...... */
+ /*0116:*/ 0x40, /* .#...... */
+ /*0117:*/ 0x80, /* #....... */
+/* --- new character less (60) starting at offset 0x0118 --- */
+ /*0118:*/ 5, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*011d:*/ 0x20, /* ..#..... */
+ /*011e:*/ 0x40, /* .#...... */
+ /*011f:*/ 0x80, /* #....... */
+ /*0120:*/ 0x40, /* .#...... */
+ /*0121:*/ 0x20, /* ..#..... */
+/* --- new character equal (61) starting at offset 0x0122 --- */
+ /*0122:*/ 4, 3, 3, 1, 1, /* width and bbox (w,h,x,y) */
+ /*0127:*/ 0xe0, /* ###..... */
+ /*0128:*/ 0x00, /* ........ */
+ /*0129:*/ 0xe0, /* ###..... */
+/* --- new character greater (62) starting at offset 0x012a --- */
+ /*012a:*/ 5, 3, 5, 2, 0, /* width and bbox (w,h,x,y) */
+ /*012f:*/ 0x80, /* #....... */
+ /*0130:*/ 0x40, /* .#...... */
+ /*0131:*/ 0x20, /* ..#..... */
+ /*0132:*/ 0x40, /* .#...... */
+ /*0133:*/ 0x80, /* #....... */
+/* --- new character question (63) starting at offset 0x0134 --- */
+ /*0134:*/ 5, 3, 5, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0139:*/ 0xc0, /* ##...... */
+ /*013a:*/ 0x20, /* ..#..... */
+ /*013b:*/ 0x40, /* .#...... */
+ /*013c:*/ 0x00, /* ........ */
+ /*013d:*/ 0x40, /* .#...... */
+/* --- new character at (64) starting at offset 0x013e --- */
+ /*013e:*/ 9, 8, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*0143:*/ 0x3e, /* ..#####. */
+ /*0144:*/ 0x41, /* .#.....# */
+ /*0145:*/ 0x99, /* #..##..# */
+ /*0146:*/ 0xa5, /* #.#..#.# */
+ /*0147:*/ 0x9e, /* #..####. */
+ /*0148:*/ 0x80, /* #....... */
+ /*0149:*/ 0x78, /* .####... */
+/* --- new character A (65) starting at offset 0x014a --- */
+ /*014a:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*014f:*/ 0x20, /* ..#..... */
+ /*0150:*/ 0x20, /* ..#..... */
+ /*0151:*/ 0x50, /* .#.#.... */
+ /*0152:*/ 0x70, /* .###.... */
+ /*0153:*/ 0x88, /* #...#... */
+ /*0154:*/ 0x88, /* #...#... */
+/* --- new character B (66) starting at offset 0x0155 --- */
+ /*0155:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*015a:*/ 0xe0, /* ###..... */
+ /*015b:*/ 0x90, /* #..#.... */
+ /*015c:*/ 0xe0, /* ###..... */
+ /*015d:*/ 0x90, /* #..#.... */
+ /*015e:*/ 0x90, /* #..#.... */
+ /*015f:*/ 0xe0, /* ###..... */
+/* --- new character C (67) starting at offset 0x0160 --- */
+ /*0160:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0165:*/ 0x70, /* .###.... */
+ /*0166:*/ 0x88, /* #...#... */
+ /*0167:*/ 0x80, /* #....... */
+ /*0168:*/ 0x80, /* #....... */
+ /*0169:*/ 0x88, /* #...#... */
+ /*016a:*/ 0x70, /* .###.... */
+/* --- new character D (68) starting at offset 0x016b --- */
+ /*016b:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0170:*/ 0xf0, /* ####.... */
+ /*0171:*/ 0x88, /* #...#... */
+ /*0172:*/ 0x88, /* #...#... */
+ /*0173:*/ 0x88, /* #...#... */
+ /*0174:*/ 0x88, /* #...#... */
+ /*0175:*/ 0xf0, /* ####.... */
+/* --- new character E (69) starting at offset 0x0176 --- */
+ /*0176:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*017b:*/ 0xf0, /* ####.... */
+ /*017c:*/ 0x80, /* #....... */
+ /*017d:*/ 0xe0, /* ###..... */
+ /*017e:*/ 0x80, /* #....... */
+ /*017f:*/ 0x80, /* #....... */
+ /*0180:*/ 0xf0, /* ####.... */
+/* --- new character F (70) starting at offset 0x0181 --- */
+ /*0181:*/ 5, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0186:*/ 0xf0, /* ####.... */
+ /*0187:*/ 0x80, /* #....... */
+ /*0188:*/ 0xe0, /* ###..... */
+ /*0189:*/ 0x80, /* #....... */
+ /*018a:*/ 0x80, /* #....... */
+ /*018b:*/ 0x80, /* #....... */
+/* --- new character G (71) starting at offset 0x018c --- */
+ /*018c:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0191:*/ 0x70, /* .###.... */
+ /*0192:*/ 0x80, /* #....... */
+ /*0193:*/ 0x98, /* #..##... */
+ /*0194:*/ 0x88, /* #...#... */
+ /*0195:*/ 0x88, /* #...#... */
+ /*0196:*/ 0x70, /* .###.... */
+/* --- new character H (72) starting at offset 0x0197 --- */
+ /*0197:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*019c:*/ 0x88, /* #...#... */
+ /*019d:*/ 0x88, /* #...#... */
+ /*019e:*/ 0xf8, /* #####... */
+ /*019f:*/ 0x88, /* #...#... */
+ /*01a0:*/ 0x88, /* #...#... */
+ /*01a1:*/ 0x88, /* #...#... */
+/* --- new character I (73) starting at offset 0x01a2 --- */
+ /*01a2:*/ 2, 1, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01a7:*/ 0x80, /* #....... */
+ /*01a8:*/ 0x80, /* #....... */
+ /*01a9:*/ 0x80, /* #....... */
+ /*01aa:*/ 0x80, /* #....... */
+ /*01ab:*/ 0x80, /* #....... */
+ /*01ac:*/ 0x80, /* #....... */
+/* --- new character J (74) starting at offset 0x01ad --- */
+ /*01ad:*/ 4, 3, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01b2:*/ 0x20, /* ..#..... */
+ /*01b3:*/ 0x20, /* ..#..... */
+ /*01b4:*/ 0x20, /* ..#..... */
+ /*01b5:*/ 0x20, /* ..#..... */
+ /*01b6:*/ 0xa0, /* #.#..... */
+ /*01b7:*/ 0x40, /* .#...... */
+/* --- new character K (75) starting at offset 0x01b8 --- */
+ /*01b8:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*01bd:*/ 0x90, /* #..#.... */
+ /*01be:*/ 0xa0, /* #.#..... */
+ /*01bf:*/ 0xc0, /* ##...... */
+ /*01c0:*/ 0xe0, /* ###..... */
+ /*01c1:*/ 0x90, /* #..#.... */
+ /*01c2:*/ 0x90, /* #..#.... */
+/* --- new character L (76) starting at offset 0x01c3 --- */
+ /*01c3:*/ 5, 3, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*01c8:*/ 0x80, /* #....... */
+ /*01c9:*/ 0x80, /* #....... */
+ /*01ca:*/ 0x80, /* #....... */
+ /*01cb:*/ 0x80, /* #....... */
+ /*01cc:*/ 0x80, /* #....... */
+ /*01cd:*/ 0xe0, /* ###..... */
+/* --- new character M (77) starting at offset 0x01ce --- */
+ /*01ce:*/ 7, 5, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*01d3:*/ 0x88, /* #...#... */
+ /*01d4:*/ 0xd8, /* ##.##... */
+ /*01d5:*/ 0xa8, /* #.#.#... */
+ /*01d6:*/ 0xa8, /* #.#.#... */
+ /*01d7:*/ 0xa8, /* #.#.#... */
+ /*01d8:*/ 0xa8, /* #.#.#... */
+/* --- new character N (78) starting at offset 0x01d9 --- */
+ /*01d9:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01de:*/ 0x88, /* #...#... */
+ /*01df:*/ 0xc8, /* ##..#... */
+ /*01e0:*/ 0xa8, /* #.#.#... */
+ /*01e1:*/ 0xa8, /* #.#.#... */
+ /*01e2:*/ 0x98, /* #..##... */
+ /*01e3:*/ 0x88, /* #...#... */
+/* --- new character O (79) starting at offset 0x01e4 --- */
+ /*01e4:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01e9:*/ 0x70, /* .###.... */
+ /*01ea:*/ 0x88, /* #...#... */
+ /*01eb:*/ 0x88, /* #...#... */
+ /*01ec:*/ 0x88, /* #...#... */
+ /*01ed:*/ 0x88, /* #...#... */
+ /*01ee:*/ 0x70, /* .###.... */
+/* --- new character P (80) starting at offset 0x01ef --- */
+ /*01ef:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*01f4:*/ 0xe0, /* ###..... */
+ /*01f5:*/ 0x90, /* #..#.... */
+ /*01f6:*/ 0x90, /* #..#.... */
+ /*01f7:*/ 0xe0, /* ###..... */
+ /*01f8:*/ 0x80, /* #....... */
+ /*01f9:*/ 0x80, /* #....... */
+/* --- new character Q (81) starting at offset 0x01fa --- */
+ /*01fa:*/ 6, 5, 8, 1, -2, /* width and bbox (w,h,x,y) */
+ /*01ff:*/ 0x70, /* .###.... */
+ /*0200:*/ 0x88, /* #...#... */
+ /*0201:*/ 0x88, /* #...#... */
+ /*0202:*/ 0x88, /* #...#... */
+ /*0203:*/ 0x88, /* #...#... */
+ /*0204:*/ 0x70, /* .###.... */
+ /*0205:*/ 0x20, /* ..#..... */
+ /*0206:*/ 0x10, /* ...#.... */
+/* --- new character R (82) starting at offset 0x0207 --- */
+ /*0207:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*020c:*/ 0xe0, /* ###..... */
+ /*020d:*/ 0x90, /* #..#.... */
+ /*020e:*/ 0x90, /* #..#.... */
+ /*020f:*/ 0xe0, /* ###..... */
+ /*0210:*/ 0x90, /* #..#.... */
+ /*0211:*/ 0x90, /* #..#.... */
+/* --- new character S (83) starting at offset 0x0212 --- */
+ /*0212:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0217:*/ 0x70, /* .###.... */
+ /*0218:*/ 0x80, /* #....... */
+ /*0219:*/ 0xe0, /* ###..... */
+ /*021a:*/ 0x10, /* ...#.... */
+ /*021b:*/ 0x10, /* ...#.... */
+ /*021c:*/ 0xe0, /* ###..... */
+/* --- new character T (84) starting at offset 0x021d --- */
+ /*021d:*/ 4, 3, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0222:*/ 0xe0, /* ###..... */
+ /*0223:*/ 0x40, /* .#...... */
+ /*0224:*/ 0x40, /* .#...... */
+ /*0225:*/ 0x40, /* .#...... */
+ /*0226:*/ 0x40, /* .#...... */
+ /*0227:*/ 0x40, /* .#...... */
+/* --- new character U (85) starting at offset 0x0228 --- */
+ /*0228:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*022d:*/ 0x88, /* #...#... */
+ /*022e:*/ 0x88, /* #...#... */
+ /*022f:*/ 0x88, /* #...#... */
+ /*0230:*/ 0x88, /* #...#... */
+ /*0231:*/ 0x88, /* #...#... */
+ /*0232:*/ 0x70, /* .###.... */
+/* --- new character V (86) starting at offset 0x0233 --- */
+ /*0233:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0238:*/ 0x90, /* #..#.... */
+ /*0239:*/ 0x90, /* #..#.... */
+ /*023a:*/ 0x90, /* #..#.... */
+ /*023b:*/ 0x90, /* #..#.... */
+ /*023c:*/ 0xa0, /* #.#..... */
+ /*023d:*/ 0x40, /* .#...... */
+/* --- new character W (87) starting at offset 0x023e --- */
+ /*023e:*/ 7, 7, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0243:*/ 0x92, /* #..#..#. */
+ /*0244:*/ 0x92, /* #..#..#. */
+ /*0245:*/ 0x92, /* #..#..#. */
+ /*0246:*/ 0x6c, /* .##.##.. */
+ /*0247:*/ 0x48, /* .#..#... */
+ /*0248:*/ 0x48, /* .#..#... */
+/* --- new character X (88) starting at offset 0x0249 --- */
+ /*0249:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*024e:*/ 0x90, /* #..#.... */
+ /*024f:*/ 0x90, /* #..#.... */
+ /*0250:*/ 0x60, /* .##..... */
+ /*0251:*/ 0x60, /* .##..... */
+ /*0252:*/ 0x90, /* #..#.... */
+ /*0253:*/ 0x90, /* #..#.... */
+/* --- new character Y (89) starting at offset 0x0254 --- */
+ /*0254:*/ 6, 5, 6, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0259:*/ 0xc8, /* ##..#... */
+ /*025a:*/ 0x48, /* .#..#... */
+ /*025b:*/ 0x48, /* .#..#... */
+ /*025c:*/ 0x30, /* ..##.... */
+ /*025d:*/ 0x20, /* ..#..... */
+ /*025e:*/ 0x20, /* ..#..... */
+/* --- new character Z (90) starting at offset 0x025f --- */
+ /*025f:*/ 6, 4, 6, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0264:*/ 0xf0, /* ####.... */
+ /*0265:*/ 0x10, /* ...#.... */
+ /*0266:*/ 0x20, /* ..#..... */
+ /*0267:*/ 0x40, /* .#...... */
+ /*0268:*/ 0x80, /* #....... */
+ /*0269:*/ 0xf0, /* ####.... */
+/* --- new character bracketleft (91) starting at offset 0x026a --- */
+ /*026a:*/ 2, 2, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*026f:*/ 0xc0, /* ##...... */
+ /*0270:*/ 0x80, /* #....... */
+ /*0271:*/ 0x80, /* #....... */
+ /*0272:*/ 0x80, /* #....... */
+ /*0273:*/ 0x80, /* #....... */
+ /*0274:*/ 0x80, /* #....... */
+ /*0275:*/ 0xc0, /* ##...... */
+/* --- new character backslash (92) starting at offset 0x0276 --- */
+ /*0276:*/ 2, 2, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*027b:*/ 0x80, /* #....... */
+ /*027c:*/ 0x80, /* #....... */
+ /*027d:*/ 0x80, /* #....... */
+ /*027e:*/ 0x40, /* .#...... */
+ /*027f:*/ 0x40, /* .#...... */
+ /*0280:*/ 0x40, /* .#...... */
+ /*0281:*/ 0x40, /* .#...... */
+/* --- new character bracketright (93) starting at offset 0x0282 --- */
+ /*0282:*/ 2, 2, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*0287:*/ 0xc0, /* ##...... */
+ /*0288:*/ 0x40, /* .#...... */
+ /*0289:*/ 0x40, /* .#...... */
+ /*028a:*/ 0x40, /* .#...... */
+ /*028b:*/ 0x40, /* .#...... */
+ /*028c:*/ 0x40, /* .#...... */
+ /*028d:*/ 0xc0, /* ##...... */
+/* --- new character asciicircum (94) starting at offset 0x028e --- */
+ /*028e:*/ 5, 5, 3, 0, 2, /* width and bbox (w,h,x,y) */
+ /*0293:*/ 0x20, /* ..#..... */
+ /*0294:*/ 0x50, /* .#.#.... */
+ /*0295:*/ 0x88, /* #...#... */
+/* --- new character underscore (95) starting at offset 0x0296 --- */
+ /*0296:*/ 5, 5, 1, 0, -1, /* width and bbox (w,h,x,y) */
+ /*029b:*/ 0xf8, /* #####... */
+/* --- new character grave (96) starting at offset 0x029c --- */
+ /*029c:*/ 3, 2, 2, 0, 6, /* width and bbox (w,h,x,y) */
+ /*02a1:*/ 0x80, /* #....... */
+ /*02a2:*/ 0x40, /* .#...... */
+/* --- new character a (97) starting at offset 0x02a3 --- */
+ /*02a3:*/ 4, 4, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02a8:*/ 0xc0, /* ##...... */
+ /*02a9:*/ 0x20, /* ..#..... */
+ /*02aa:*/ 0xe0, /* ###..... */
+ /*02ab:*/ 0xa0, /* #.#..... */
+ /*02ac:*/ 0xd0, /* ##.#.... */
+/* --- new character b (98) starting at offset 0x02ad --- */
+ /*02ad:*/ 5, 4, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02b2:*/ 0x80, /* #....... */
+ /*02b3:*/ 0x80, /* #....... */
+ /*02b4:*/ 0xe0, /* ###..... */
+ /*02b5:*/ 0x90, /* #..#.... */
+ /*02b6:*/ 0x90, /* #..#.... */
+ /*02b7:*/ 0x90, /* #..#.... */
+ /*02b8:*/ 0xe0, /* ###..... */
+/* --- new character c (99) starting at offset 0x02b9 --- */
+ /*02b9:*/ 4, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02be:*/ 0x60, /* .##..... */
+ /*02bf:*/ 0x80, /* #....... */
+ /*02c0:*/ 0x80, /* #....... */
+ /*02c1:*/ 0x80, /* #....... */
+ /*02c2:*/ 0x60, /* .##..... */
+/* --- new character d (100) starting at offset 0x02c3 --- */
+ /*02c3:*/ 5, 4, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02c8:*/ 0x10, /* ...#.... */
+ /*02c9:*/ 0x10, /* ...#.... */
+ /*02ca:*/ 0x70, /* .###.... */
+ /*02cb:*/ 0x90, /* #..#.... */
+ /*02cc:*/ 0x90, /* #..#.... */
+ /*02cd:*/ 0x90, /* #..#.... */
+ /*02ce:*/ 0x70, /* .###.... */
+/* --- new character e (101) starting at offset 0x02cf --- */
+ /*02cf:*/ 4, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02d4:*/ 0x40, /* .#...... */
+ /*02d5:*/ 0xa0, /* #.#..... */
+ /*02d6:*/ 0xe0, /* ###..... */
+ /*02d7:*/ 0x80, /* #....... */
+ /*02d8:*/ 0x60, /* .##..... */
+/* --- new character f (102) starting at offset 0x02d9 --- */
+ /*02d9:*/ 4, 3, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02de:*/ 0x20, /* ..#..... */
+ /*02df:*/ 0x40, /* .#...... */
+ /*02e0:*/ 0xe0, /* ###..... */
+ /*02e1:*/ 0x40, /* .#...... */
+ /*02e2:*/ 0x40, /* .#...... */
+ /*02e3:*/ 0x40, /* .#...... */
+ /*02e4:*/ 0x40, /* .#...... */
+/* --- new character g (103) starting at offset 0x02e5 --- */
+ /*02e5:*/ 5, 4, 6, 1, -1, /* width and bbox (w,h,x,y) */
+ /*02ea:*/ 0x70, /* .###.... */
+ /*02eb:*/ 0x90, /* #..#.... */
+ /*02ec:*/ 0x90, /* #..#.... */
+ /*02ed:*/ 0x70, /* .###.... */
+ /*02ee:*/ 0x10, /* ...#.... */
+ /*02ef:*/ 0x60, /* .##..... */
+/* --- new character h (104) starting at offset 0x02f0 --- */
+ /*02f0:*/ 5, 4, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02f5:*/ 0x80, /* #....... */
+ /*02f6:*/ 0x80, /* #....... */
+ /*02f7:*/ 0xe0, /* ###..... */
+ /*02f8:*/ 0x90, /* #..#.... */
+ /*02f9:*/ 0x90, /* #..#.... */
+ /*02fa:*/ 0x90, /* #..#.... */
+ /*02fb:*/ 0x90, /* #..#.... */
+/* --- new character i (105) starting at offset 0x02fc --- */
+ /*02fc:*/ 2, 1, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0301:*/ 0x80, /* #....... */
+ /*0302:*/ 0x00, /* ........ */
+ /*0303:*/ 0x80, /* #....... */
+ /*0304:*/ 0x80, /* #....... */
+ /*0305:*/ 0x80, /* #....... */
+ /*0306:*/ 0x80, /* #....... */
+ /*0307:*/ 0x80, /* #....... */
+/* --- new character j (106) starting at offset 0x0308 --- */
+ /*0308:*/ 2, 2, 9, 0, -2, /* width and bbox (w,h,x,y) */
+ /*030d:*/ 0x40, /* .#...... */
+ /*030e:*/ 0x00, /* ........ */
+ /*030f:*/ 0x40, /* .#...... */
+ /*0310:*/ 0x40, /* .#...... */
+ /*0311:*/ 0x40, /* .#...... */
+ /*0312:*/ 0x40, /* .#...... */
+ /*0313:*/ 0x40, /* .#...... */
+ /*0314:*/ 0x40, /* .#...... */
+ /*0315:*/ 0x80, /* #....... */
+/* --- new character k (107) starting at offset 0x0316 --- */
+ /*0316:*/ 4, 3, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*031b:*/ 0x80, /* #....... */
+ /*031c:*/ 0x80, /* #....... */
+ /*031d:*/ 0xa0, /* #.#..... */
+ /*031e:*/ 0xc0, /* ##...... */
+ /*031f:*/ 0xc0, /* ##...... */
+ /*0320:*/ 0xa0, /* #.#..... */
+ /*0321:*/ 0xa0, /* #.#..... */
+/* --- new character l (108) starting at offset 0x0322 --- */
+ /*0322:*/ 2, 1, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0327:*/ 0x80, /* #....... */
+ /*0328:*/ 0x80, /* #....... */
+ /*0329:*/ 0x80, /* #....... */
+ /*032a:*/ 0x80, /* #....... */
+ /*032b:*/ 0x80, /* #....... */
+ /*032c:*/ 0x80, /* #....... */
+ /*032d:*/ 0x80, /* #....... */
+/* --- new character m (109) starting at offset 0x032e --- */
+ /*032e:*/ 6, 5, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0333:*/ 0xf0, /* ####.... */
+ /*0334:*/ 0xa8, /* #.#.#... */
+ /*0335:*/ 0xa8, /* #.#.#... */
+ /*0336:*/ 0xa8, /* #.#.#... */
+ /*0337:*/ 0xa8, /* #.#.#... */
+/* --- new character n (110) starting at offset 0x0338 --- */
+ /*0338:*/ 5, 4, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*033d:*/ 0xe0, /* ###..... */
+ /*033e:*/ 0x90, /* #..#.... */
+ /*033f:*/ 0x90, /* #..#.... */
+ /*0340:*/ 0x90, /* #..#.... */
+ /*0341:*/ 0x90, /* #..#.... */
+/* --- new character o (111) starting at offset 0x0342 --- */
+ /*0342:*/ 5, 4, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0347:*/ 0x60, /* .##..... */
+ /*0348:*/ 0x90, /* #..#.... */
+ /*0349:*/ 0x90, /* #..#.... */
+ /*034a:*/ 0x90, /* #..#.... */
+ /*034b:*/ 0x60, /* .##..... */
+/* --- new character p (112) starting at offset 0x034c --- */
+ /*034c:*/ 5, 4, 6, 1, -1, /* width and bbox (w,h,x,y) */
+ /*0351:*/ 0xe0, /* ###..... */
+ /*0352:*/ 0x90, /* #..#.... */
+ /*0353:*/ 0x90, /* #..#.... */
+ /*0354:*/ 0x90, /* #..#.... */
+ /*0355:*/ 0xe0, /* ###..... */
+ /*0356:*/ 0x80, /* #....... */
+/* --- new character q (113) starting at offset 0x0357 --- */
+ /*0357:*/ 5, 4, 6, 1, -1, /* width and bbox (w,h,x,y) */
+ /*035c:*/ 0x70, /* .###.... */
+ /*035d:*/ 0x90, /* #..#.... */
+ /*035e:*/ 0x90, /* #..#.... */
+ /*035f:*/ 0x90, /* #..#.... */
+ /*0360:*/ 0x70, /* .###.... */
+ /*0361:*/ 0x10, /* ...#.... */
+/* --- new character r (114) starting at offset 0x0362 --- */
+ /*0362:*/ 3, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0367:*/ 0xa0, /* #.#..... */
+ /*0368:*/ 0xc0, /* ##...... */
+ /*0369:*/ 0x80, /* #....... */
+ /*036a:*/ 0x80, /* #....... */
+ /*036b:*/ 0x80, /* #....... */
+/* --- new character s (115) starting at offset 0x036c --- */
+ /*036c:*/ 4, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0371:*/ 0x60, /* .##..... */
+ /*0372:*/ 0x80, /* #....... */
+ /*0373:*/ 0x60, /* .##..... */
+ /*0374:*/ 0x20, /* ..#..... */
+ /*0375:*/ 0xc0, /* ##...... */
+/* --- new character t (116) starting at offset 0x0376 --- */
+ /*0376:*/ 3, 3, 7, 1, 0, /* width and bbox (w,h,x,y) */
+ /*037b:*/ 0x40, /* .#...... */
+ /*037c:*/ 0x40, /* .#...... */
+ /*037d:*/ 0xe0, /* ###..... */
+ /*037e:*/ 0x40, /* .#...... */
+ /*037f:*/ 0x40, /* .#...... */
+ /*0380:*/ 0x40, /* .#...... */
+ /*0381:*/ 0x40, /* .#...... */
+/* --- new character u (117) starting at offset 0x0382 --- */
+ /*0382:*/ 4, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0387:*/ 0xa0, /* #.#..... */
+ /*0388:*/ 0xa0, /* #.#..... */
+ /*0389:*/ 0xa0, /* #.#..... */
+ /*038a:*/ 0xa0, /* #.#..... */
+ /*038b:*/ 0x60, /* .##..... */
+/* --- new character v (118) starting at offset 0x038c --- */
+ /*038c:*/ 5, 4, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0391:*/ 0x90, /* #..#.... */
+ /*0392:*/ 0x90, /* #..#.... */
+ /*0393:*/ 0x90, /* #..#.... */
+ /*0394:*/ 0xa0, /* #.#..... */
+ /*0395:*/ 0x40, /* .#...... */
+/* --- new character w (119) starting at offset 0x0396 --- */
+ /*0396:*/ 6, 5, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*039b:*/ 0xa8, /* #.#.#... */
+ /*039c:*/ 0xa8, /* #.#.#... */
+ /*039d:*/ 0xa8, /* #.#.#... */
+ /*039e:*/ 0x50, /* .#.#.... */
+ /*039f:*/ 0x50, /* .#.#.... */
+/* --- new character x (120) starting at offset 0x03a0 --- */
+ /*03a0:*/ 5, 4, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*03a5:*/ 0x90, /* #..#.... */
+ /*03a6:*/ 0x90, /* #..#.... */
+ /*03a7:*/ 0x60, /* .##..... */
+ /*03a8:*/ 0x90, /* #..#.... */
+ /*03a9:*/ 0x90, /* #..#.... */
+/* --- new character y (121) starting at offset 0x03aa --- */
+ /*03aa:*/ 4, 4, 6, 1, -1, /* width and bbox (w,h,x,y) */
+ /*03af:*/ 0x90, /* #..#.... */
+ /*03b0:*/ 0x90, /* #..#.... */
+ /*03b1:*/ 0x90, /* #..#.... */
+ /*03b2:*/ 0x60, /* .##..... */
+ /*03b3:*/ 0x40, /* .#...... */
+ /*03b4:*/ 0x80, /* #....... */
+/* --- new character z (122) starting at offset 0x03b5 --- */
+ /*03b5:*/ 4, 3, 5, 1, 0, /* width and bbox (w,h,x,y) */
+ /*03ba:*/ 0xe0, /* ###..... */
+ /*03bb:*/ 0x20, /* ..#..... */
+ /*03bc:*/ 0x40, /* .#...... */
+ /*03bd:*/ 0x80, /* #....... */
+ /*03be:*/ 0xe0, /* ###..... */
+/* --- new character braceleft (123) starting at offset 0x03bf --- */
+ /*03bf:*/ 2, 3, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*03c4:*/ 0x20, /* ..#..... */
+ /*03c5:*/ 0x40, /* .#...... */
+ /*03c6:*/ 0x40, /* .#...... */
+ /*03c7:*/ 0xc0, /* ##...... */
+ /*03c8:*/ 0x40, /* .#...... */
+ /*03c9:*/ 0x40, /* .#...... */
+ /*03ca:*/ 0x20, /* ..#..... */
+/* --- new character bar (124) starting at offset 0x03cb --- */
+ /*03cb:*/ 2, 1, 7, 1, -1, /* width and bbox (w,h,x,y) */
+ /*03d0:*/ 0x80, /* #....... */
+ /*03d1:*/ 0x80, /* #....... */
+ /*03d2:*/ 0x80, /* #....... */
+ /*03d3:*/ 0x80, /* #....... */
+ /*03d4:*/ 0x80, /* #....... */
+ /*03d5:*/ 0x80, /* #....... */
+ /*03d6:*/ 0x80, /* #....... */
+/* --- new character braceright (125) starting at offset 0x03d7 --- */
+ /*03d7:*/ 2, 3, 7, 0, -1, /* width and bbox (w,h,x,y) */
+ /*03dc:*/ 0x80, /* #....... */
+ /*03dd:*/ 0x40, /* .#...... */
+ /*03de:*/ 0x40, /* .#...... */
+ /*03df:*/ 0x60, /* .##..... */
+ /*03e0:*/ 0x40, /* .#...... */
+ /*03e1:*/ 0x40, /* .#...... */
+ /*03e2:*/ 0x80, /* #....... */
+/* --- new character asciitilde (126) starting at offset 0x03e3 --- */
+ /*03e3:*/ 6, 5, 2, 1, 2, /* width and bbox (w,h,x,y) */
+ /*03e8:*/ 0x48, /* .#..#... */
+ /*03e9:*/ 0xb0, /* #.##.... */
+};
+static const uint16_t font_helvR08_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x0011 /* quotedbl */,
+ 0x0019 /* numbersign */,
+ 0x0023 /* dollar */,
+ 0x002f /* percent */,
+ 0x003a /* ampersand */,
+ 0x0045 /* quotesingle */,
+ 0x004c /* parenleft */,
+ 0x0058 /* parenright */,
+ 0x0064 /* asterisk */,
+ 0x006c /* plus */,
+ 0x0076 /* comma */,
+ 0x007e /* hyphen */,
+ 0x0084 /* period */,
+ 0x008a /* slash */,
+ 0x0096 /* zero */,
+ 0x00a1 /* one */,
+ 0x00ac /* two */,
+ 0x00b7 /* three */,
+ 0x00c2 /* four */,
+ 0x00cd /* five */,
+ 0x00d8 /* six */,
+ 0x00e3 /* seven */,
+ 0x00ee /* eight */,
+ 0x00f9 /* nine */,
+ 0x0104 /* colon */,
+ 0x010d /* semicolon */,
+ 0x0118 /* less */,
+ 0x0122 /* equal */,
+ 0x012a /* greater */,
+ 0x0134 /* question */,
+ 0x013e /* at */,
+ 0x014a /* A */,
+ 0x0155 /* B */,
+ 0x0160 /* C */,
+ 0x016b /* D */,
+ 0x0176 /* E */,
+ 0x0181 /* F */,
+ 0x018c /* G */,
+ 0x0197 /* H */,
+ 0x01a2 /* I */,
+ 0x01ad /* J */,
+ 0x01b8 /* K */,
+ 0x01c3 /* L */,
+ 0x01ce /* M */,
+ 0x01d9 /* N */,
+ 0x01e4 /* O */,
+ 0x01ef /* P */,
+ 0x01fa /* Q */,
+ 0x0207 /* R */,
+ 0x0212 /* S */,
+ 0x021d /* T */,
+ 0x0228 /* U */,
+ 0x0233 /* V */,
+ 0x023e /* W */,
+ 0x0249 /* X */,
+ 0x0254 /* Y */,
+ 0x025f /* Z */,
+ 0x026a /* bracketleft */,
+ 0x0276 /* backslash */,
+ 0x0282 /* bracketright */,
+ 0x028e /* asciicircum */,
+ 0x0296 /* underscore */,
+ 0x029c /* grave */,
+ 0x02a3 /* a */,
+ 0x02ad /* b */,
+ 0x02b9 /* c */,
+ 0x02c3 /* d */,
+ 0x02cf /* e */,
+ 0x02d9 /* f */,
+ 0x02e5 /* g */,
+ 0x02f0 /* h */,
+ 0x02fc /* i */,
+ 0x0308 /* j */,
+ 0x0316 /* k */,
+ 0x0322 /* l */,
+ 0x032e /* m */,
+ 0x0338 /* n */,
+ 0x0342 /* o */,
+ 0x034c /* p */,
+ 0x0357 /* q */,
+ 0x0362 /* r */,
+ 0x036c /* s */,
+ 0x0376 /* t */,
+ 0x0382 /* u */,
+ 0x038c /* v */,
+ 0x0396 /* w */,
+ 0x03a0 /* x */,
+ 0x03aa /* y */,
+ 0x03b5 /* z */,
+ 0x03bf /* braceleft */,
+ 0x03cb /* bar */,
+ 0x03d7 /* braceright */,
+ 0x03e3 /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_helvR08 = {
+ .height = 10,
+ .ascent = 8,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_helvR08_data,
+ .charoffs = font_helvR08_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/helvR14.c b/Src/osmolib/src/target/firmware/fb/helvR14.c
new file mode 100644
index 0000000..b028125
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/helvR14.c
@@ -0,0 +1,1198 @@
+#include <fb/font.h>
+static const uint8_t font_helvR14_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 4, 1, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 4, 1, 11, 2, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0x80, /* #....... */
+ /*000c:*/ 0x80, /* #....... */
+ /*000d:*/ 0x80, /* #....... */
+ /*000e:*/ 0x80, /* #....... */
+ /*000f:*/ 0x80, /* #....... */
+ /*0010:*/ 0x80, /* #....... */
+ /*0011:*/ 0x80, /* #....... */
+ /*0012:*/ 0x80, /* #....... */
+ /*0013:*/ 0x00, /* ........ */
+ /*0014:*/ 0x80, /* #....... */
+ /*0015:*/ 0x80, /* #....... */
+/* --- new character quotedbl (34) starting at offset 0x0016 --- */
+ /*0016:*/ 5, 3, 3, 1, 8, /* width and bbox (w,h,x,y) */
+ /*001b:*/ 0xa0, /* #.#..... */
+ /*001c:*/ 0xa0, /* #.#..... */
+ /*001d:*/ 0xa0, /* #.#..... */
+/* --- new character numbersign (35) starting at offset 0x001e --- */
+ /*001e:*/ 8, 7, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0023:*/ 0x14, /* ...#.#.. */
+ /*0024:*/ 0x14, /* ...#.#.. */
+ /*0025:*/ 0x14, /* ...#.#.. */
+ /*0026:*/ 0x7e, /* .######. */
+ /*0027:*/ 0x28, /* ..#.#... */
+ /*0028:*/ 0x28, /* ..#.#... */
+ /*0029:*/ 0xfc, /* ######.. */
+ /*002a:*/ 0x50, /* .#.#.... */
+ /*002b:*/ 0x50, /* .#.#.... */
+ /*002c:*/ 0x50, /* .#.#.... */
+/* --- new character dollar (36) starting at offset 0x002d --- */
+ /*002d:*/ 8, 7, 14, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0032:*/ 0x10, /* ...#.... */
+ /*0033:*/ 0x10, /* ...#.... */
+ /*0034:*/ 0x7c, /* .#####.. */
+ /*0035:*/ 0x92, /* #..#..#. */
+ /*0036:*/ 0x92, /* #..#..#. */
+ /*0037:*/ 0x50, /* .#.#.... */
+ /*0038:*/ 0x38, /* ..###... */
+ /*0039:*/ 0x14, /* ...#.#.. */
+ /*003a:*/ 0x12, /* ...#..#. */
+ /*003b:*/ 0x92, /* #..#..#. */
+ /*003c:*/ 0x92, /* #..#..#. */
+ /*003d:*/ 0x7c, /* .#####.. */
+ /*003e:*/ 0x10, /* ...#.... */
+ /*003f:*/ 0x10, /* ...#.... */
+/* --- new character percent (37) starting at offset 0x0040 --- */
+ /*0040:*/ 12, 11, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0045:*/ 0x70,0x80, /* .###....#....... */
+ /*0047:*/ 0x89,0x00, /* #...#..#........ */
+ /*0049:*/ 0x89,0x00, /* #...#..#........ */
+ /*004b:*/ 0x72,0x00, /* .###..#......... */
+ /*004d:*/ 0x02,0x00, /* ......#......... */
+ /*004f:*/ 0x04,0x00, /* .....#.......... */
+ /*0051:*/ 0x09,0xc0, /* ....#..###...... */
+ /*0053:*/ 0x12,0x20, /* ...#..#...#..... */
+ /*0055:*/ 0x12,0x20, /* ...#..#...#..... */
+ /*0057:*/ 0x21,0xc0, /* ..#....###...... */
+/* --- new character ampersand (38) starting at offset 0x0059 --- */
+ /*0059:*/ 10, 8, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*005e:*/ 0x30, /* ..##.... */
+ /*005f:*/ 0x48, /* .#..#... */
+ /*0060:*/ 0x48, /* .#..#... */
+ /*0061:*/ 0x30, /* ..##.... */
+ /*0062:*/ 0x20, /* ..#..... */
+ /*0063:*/ 0x52, /* .#.#..#. */
+ /*0064:*/ 0x8a, /* #...#.#. */
+ /*0065:*/ 0x84, /* #....#.. */
+ /*0066:*/ 0x8a, /* #...#.#. */
+ /*0067:*/ 0x71, /* .###...# */
+/* --- new character quotesingle (39) starting at offset 0x0068 --- */
+ /*0068:*/ 3, 1, 3, 1, 8, /* width and bbox (w,h,x,y) */
+ /*006d:*/ 0x80, /* #....... */
+ /*006e:*/ 0x80, /* #....... */
+ /*006f:*/ 0x80, /* #....... */
+/* --- new character parenleft (40) starting at offset 0x0070 --- */
+ /*0070:*/ 5, 3, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0075:*/ 0x20, /* ..#..... */
+ /*0076:*/ 0x40, /* .#...... */
+ /*0077:*/ 0x40, /* .#...... */
+ /*0078:*/ 0x80, /* #....... */
+ /*0079:*/ 0x80, /* #....... */
+ /*007a:*/ 0x80, /* #....... */
+ /*007b:*/ 0x80, /* #....... */
+ /*007c:*/ 0x80, /* #....... */
+ /*007d:*/ 0x80, /* #....... */
+ /*007e:*/ 0x80, /* #....... */
+ /*007f:*/ 0x80, /* #....... */
+ /*0080:*/ 0x40, /* .#...... */
+ /*0081:*/ 0x40, /* .#...... */
+ /*0082:*/ 0x20, /* ..#..... */
+/* --- new character parenright (41) starting at offset 0x0083 --- */
+ /*0083:*/ 5, 3, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0088:*/ 0x80, /* #....... */
+ /*0089:*/ 0x40, /* .#...... */
+ /*008a:*/ 0x40, /* .#...... */
+ /*008b:*/ 0x20, /* ..#..... */
+ /*008c:*/ 0x20, /* ..#..... */
+ /*008d:*/ 0x20, /* ..#..... */
+ /*008e:*/ 0x20, /* ..#..... */
+ /*008f:*/ 0x20, /* ..#..... */
+ /*0090:*/ 0x20, /* ..#..... */
+ /*0091:*/ 0x20, /* ..#..... */
+ /*0092:*/ 0x20, /* ..#..... */
+ /*0093:*/ 0x40, /* .#...... */
+ /*0094:*/ 0x40, /* .#...... */
+ /*0095:*/ 0x80, /* #....... */
+/* --- new character asterisk (42) starting at offset 0x0096 --- */
+ /*0096:*/ 7, 5, 4, 1, 6, /* width and bbox (w,h,x,y) */
+ /*009b:*/ 0x20, /* ..#..... */
+ /*009c:*/ 0xf8, /* #####... */
+ /*009d:*/ 0x20, /* ..#..... */
+ /*009e:*/ 0x50, /* .#.#.... */
+/* --- new character plus (43) starting at offset 0x009f --- */
+ /*009f:*/ 9, 7, 7, 1, 1, /* width and bbox (w,h,x,y) */
+ /*00a4:*/ 0x10, /* ...#.... */
+ /*00a5:*/ 0x10, /* ...#.... */
+ /*00a6:*/ 0x10, /* ...#.... */
+ /*00a7:*/ 0xfe, /* #######. */
+ /*00a8:*/ 0x10, /* ...#.... */
+ /*00a9:*/ 0x10, /* ...#.... */
+ /*00aa:*/ 0x10, /* ...#.... */
+/* --- new character comma (44) starting at offset 0x00ab --- */
+ /*00ab:*/ 3, 2, 4, 0, -2, /* width and bbox (w,h,x,y) */
+ /*00b0:*/ 0x40, /* .#...... */
+ /*00b1:*/ 0x40, /* .#...... */
+ /*00b2:*/ 0x40, /* .#...... */
+ /*00b3:*/ 0x80, /* #....... */
+/* --- new character hyphen (45) starting at offset 0x00b4 --- */
+ /*00b4:*/ 5, 4, 1, 0, 4, /* width and bbox (w,h,x,y) */
+ /*00b9:*/ 0xf0, /* ####.... */
+/* --- new character period (46) starting at offset 0x00ba --- */
+ /*00ba:*/ 3, 1, 2, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00bf:*/ 0x80, /* #....... */
+ /*00c0:*/ 0x80, /* #....... */
+/* --- new character slash (47) starting at offset 0x00c1 --- */
+ /*00c1:*/ 4, 4, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*00c6:*/ 0x10, /* ...#.... */
+ /*00c7:*/ 0x10, /* ...#.... */
+ /*00c8:*/ 0x20, /* ..#..... */
+ /*00c9:*/ 0x20, /* ..#..... */
+ /*00ca:*/ 0x20, /* ..#..... */
+ /*00cb:*/ 0x40, /* .#...... */
+ /*00cc:*/ 0x40, /* .#...... */
+ /*00cd:*/ 0x40, /* .#...... */
+ /*00ce:*/ 0x80, /* #....... */
+ /*00cf:*/ 0x80, /* #....... */
+ /*00d0:*/ 0x80, /* #....... */
+/* --- new character zero (48) starting at offset 0x00d1 --- */
+ /*00d1:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00d6:*/ 0x78, /* .####... */
+ /*00d7:*/ 0x84, /* #....#.. */
+ /*00d8:*/ 0x84, /* #....#.. */
+ /*00d9:*/ 0x84, /* #....#.. */
+ /*00da:*/ 0x84, /* #....#.. */
+ /*00db:*/ 0x84, /* #....#.. */
+ /*00dc:*/ 0x84, /* #....#.. */
+ /*00dd:*/ 0x84, /* #....#.. */
+ /*00de:*/ 0x84, /* #....#.. */
+ /*00df:*/ 0x78, /* .####... */
+/* --- new character one (49) starting at offset 0x00e0 --- */
+ /*00e0:*/ 8, 3, 10, 2, 0, /* width and bbox (w,h,x,y) */
+ /*00e5:*/ 0x20, /* ..#..... */
+ /*00e6:*/ 0xe0, /* ###..... */
+ /*00e7:*/ 0x20, /* ..#..... */
+ /*00e8:*/ 0x20, /* ..#..... */
+ /*00e9:*/ 0x20, /* ..#..... */
+ /*00ea:*/ 0x20, /* ..#..... */
+ /*00eb:*/ 0x20, /* ..#..... */
+ /*00ec:*/ 0x20, /* ..#..... */
+ /*00ed:*/ 0x20, /* ..#..... */
+ /*00ee:*/ 0x20, /* ..#..... */
+/* --- new character two (50) starting at offset 0x00ef --- */
+ /*00ef:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00f4:*/ 0x78, /* .####... */
+ /*00f5:*/ 0x84, /* #....#.. */
+ /*00f6:*/ 0x84, /* #....#.. */
+ /*00f7:*/ 0x08, /* ....#... */
+ /*00f8:*/ 0x10, /* ...#.... */
+ /*00f9:*/ 0x20, /* ..#..... */
+ /*00fa:*/ 0x40, /* .#...... */
+ /*00fb:*/ 0x80, /* #....... */
+ /*00fc:*/ 0x80, /* #....... */
+ /*00fd:*/ 0xfc, /* ######.. */
+/* --- new character three (51) starting at offset 0x00fe --- */
+ /*00fe:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0103:*/ 0x78, /* .####... */
+ /*0104:*/ 0x84, /* #....#.. */
+ /*0105:*/ 0x84, /* #....#.. */
+ /*0106:*/ 0x04, /* .....#.. */
+ /*0107:*/ 0x38, /* ..###... */
+ /*0108:*/ 0x04, /* .....#.. */
+ /*0109:*/ 0x04, /* .....#.. */
+ /*010a:*/ 0x84, /* #....#.. */
+ /*010b:*/ 0x84, /* #....#.. */
+ /*010c:*/ 0x78, /* .####... */
+/* --- new character four (52) starting at offset 0x010d --- */
+ /*010d:*/ 8, 7, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0112:*/ 0x0c, /* ....##.. */
+ /*0113:*/ 0x14, /* ...#.#.. */
+ /*0114:*/ 0x24, /* ..#..#.. */
+ /*0115:*/ 0x24, /* ..#..#.. */
+ /*0116:*/ 0x44, /* .#...#.. */
+ /*0117:*/ 0x84, /* #....#.. */
+ /*0118:*/ 0xfe, /* #######. */
+ /*0119:*/ 0x04, /* .....#.. */
+ /*011a:*/ 0x04, /* .....#.. */
+ /*011b:*/ 0x04, /* .....#.. */
+/* --- new character five (53) starting at offset 0x011c --- */
+ /*011c:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0121:*/ 0xfc, /* ######.. */
+ /*0122:*/ 0x80, /* #....... */
+ /*0123:*/ 0x80, /* #....... */
+ /*0124:*/ 0x80, /* #....... */
+ /*0125:*/ 0xf8, /* #####... */
+ /*0126:*/ 0x04, /* .....#.. */
+ /*0127:*/ 0x04, /* .....#.. */
+ /*0128:*/ 0x84, /* #....#.. */
+ /*0129:*/ 0x84, /* #....#.. */
+ /*012a:*/ 0x78, /* .####... */
+/* --- new character six (54) starting at offset 0x012b --- */
+ /*012b:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0130:*/ 0x78, /* .####... */
+ /*0131:*/ 0x84, /* #....#.. */
+ /*0132:*/ 0x80, /* #....... */
+ /*0133:*/ 0x80, /* #....... */
+ /*0134:*/ 0xb8, /* #.###... */
+ /*0135:*/ 0xc4, /* ##...#.. */
+ /*0136:*/ 0x84, /* #....#.. */
+ /*0137:*/ 0x84, /* #....#.. */
+ /*0138:*/ 0x84, /* #....#.. */
+ /*0139:*/ 0x78, /* .####... */
+/* --- new character seven (55) starting at offset 0x013a --- */
+ /*013a:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*013f:*/ 0xfc, /* ######.. */
+ /*0140:*/ 0x04, /* .....#.. */
+ /*0141:*/ 0x08, /* ....#... */
+ /*0142:*/ 0x08, /* ....#... */
+ /*0143:*/ 0x10, /* ...#.... */
+ /*0144:*/ 0x10, /* ...#.... */
+ /*0145:*/ 0x20, /* ..#..... */
+ /*0146:*/ 0x20, /* ..#..... */
+ /*0147:*/ 0x40, /* .#...... */
+ /*0148:*/ 0x40, /* .#...... */
+/* --- new character eight (56) starting at offset 0x0149 --- */
+ /*0149:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*014e:*/ 0x78, /* .####... */
+ /*014f:*/ 0x84, /* #....#.. */
+ /*0150:*/ 0x84, /* #....#.. */
+ /*0151:*/ 0x84, /* #....#.. */
+ /*0152:*/ 0x78, /* .####... */
+ /*0153:*/ 0x84, /* #....#.. */
+ /*0154:*/ 0x84, /* #....#.. */
+ /*0155:*/ 0x84, /* #....#.. */
+ /*0156:*/ 0x84, /* #....#.. */
+ /*0157:*/ 0x78, /* .####... */
+/* --- new character nine (57) starting at offset 0x0158 --- */
+ /*0158:*/ 8, 6, 10, 1, 0, /* width and bbox (w,h,x,y) */
+ /*015d:*/ 0x78, /* .####... */
+ /*015e:*/ 0x84, /* #....#.. */
+ /*015f:*/ 0x84, /* #....#.. */
+ /*0160:*/ 0x84, /* #....#.. */
+ /*0161:*/ 0x84, /* #....#.. */
+ /*0162:*/ 0x7c, /* .#####.. */
+ /*0163:*/ 0x04, /* .....#.. */
+ /*0164:*/ 0x84, /* #....#.. */
+ /*0165:*/ 0x84, /* #....#.. */
+ /*0166:*/ 0x78, /* .####... */
+/* --- new character colon (58) starting at offset 0x0167 --- */
+ /*0167:*/ 3, 1, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*016c:*/ 0x80, /* #....... */
+ /*016d:*/ 0x80, /* #....... */
+ /*016e:*/ 0x00, /* ........ */
+ /*016f:*/ 0x00, /* ........ */
+ /*0170:*/ 0x00, /* ........ */
+ /*0171:*/ 0x00, /* ........ */
+ /*0172:*/ 0x80, /* #....... */
+ /*0173:*/ 0x80, /* #....... */
+/* --- new character semicolon (59) starting at offset 0x0174 --- */
+ /*0174:*/ 4, 2, 10, 0, -2, /* width and bbox (w,h,x,y) */
+ /*0179:*/ 0x40, /* .#...... */
+ /*017a:*/ 0x40, /* .#...... */
+ /*017b:*/ 0x00, /* ........ */
+ /*017c:*/ 0x00, /* ........ */
+ /*017d:*/ 0x00, /* ........ */
+ /*017e:*/ 0x00, /* ........ */
+ /*017f:*/ 0x40, /* .#...... */
+ /*0180:*/ 0x40, /* .#...... */
+ /*0181:*/ 0x40, /* .#...... */
+ /*0182:*/ 0x80, /* #....... */
+/* --- new character less (60) starting at offset 0x0183 --- */
+ /*0183:*/ 8, 6, 5, 1, 2, /* width and bbox (w,h,x,y) */
+ /*0188:*/ 0x0c, /* ....##.. */
+ /*0189:*/ 0x30, /* ..##.... */
+ /*018a:*/ 0xc0, /* ##...... */
+ /*018b:*/ 0x30, /* ..##.... */
+ /*018c:*/ 0x0c, /* ....##.. */
+/* --- new character equal (61) starting at offset 0x018d --- */
+ /*018d:*/ 9, 6, 3, 1, 3, /* width and bbox (w,h,x,y) */
+ /*0192:*/ 0xfc, /* ######.. */
+ /*0193:*/ 0x00, /* ........ */
+ /*0194:*/ 0xfc, /* ######.. */
+/* --- new character greater (62) starting at offset 0x0195 --- */
+ /*0195:*/ 8, 6, 5, 1, 2, /* width and bbox (w,h,x,y) */
+ /*019a:*/ 0xc0, /* ##...... */
+ /*019b:*/ 0x30, /* ..##.... */
+ /*019c:*/ 0x0c, /* ....##.. */
+ /*019d:*/ 0x30, /* ..##.... */
+ /*019e:*/ 0xc0, /* ##...... */
+/* --- new character question (63) starting at offset 0x019f --- */
+ /*019f:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01a4:*/ 0x30, /* ..##.... */
+ /*01a5:*/ 0xcc, /* ##..##.. */
+ /*01a6:*/ 0x84, /* #....#.. */
+ /*01a7:*/ 0x84, /* #....#.. */
+ /*01a8:*/ 0x04, /* .....#.. */
+ /*01a9:*/ 0x08, /* ....#... */
+ /*01aa:*/ 0x10, /* ...#.... */
+ /*01ab:*/ 0x20, /* ..#..... */
+ /*01ac:*/ 0x00, /* ........ */
+ /*01ad:*/ 0x20, /* ..#..... */
+ /*01ae:*/ 0x20, /* ..#..... */
+/* --- new character at (64) starting at offset 0x01af --- */
+ /*01af:*/ 13, 11, 12, 1, -1, /* width and bbox (w,h,x,y) */
+ /*01b4:*/ 0x0f,0x00, /* ....####........ */
+ /*01b6:*/ 0x30,0xc0, /* ..##....##...... */
+ /*01b8:*/ 0x40,0x20, /* .#........#..... */
+ /*01ba:*/ 0x46,0xa0, /* .#...##.#.#..... */
+ /*01bc:*/ 0x89,0x20, /* #...#..#..#..... */
+ /*01be:*/ 0x91,0x20, /* #..#...#..#..... */
+ /*01c0:*/ 0x91,0x20, /* #..#...#..#..... */
+ /*01c2:*/ 0x93,0x40, /* #..#..##.#...... */
+ /*01c4:*/ 0x8d,0x80, /* #...##.##....... */
+ /*01c6:*/ 0x40,0x00, /* .#.............. */
+ /*01c8:*/ 0x60,0x80, /* .##.....#....... */
+ /*01ca:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character A (65) starting at offset 0x01cc --- */
+ /*01cc:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01d1:*/ 0x08,0x00, /* ....#........... */
+ /*01d3:*/ 0x08,0x00, /* ....#........... */
+ /*01d5:*/ 0x14,0x00, /* ...#.#.......... */
+ /*01d7:*/ 0x14,0x00, /* ...#.#.......... */
+ /*01d9:*/ 0x22,0x00, /* ..#...#......... */
+ /*01db:*/ 0x22,0x00, /* ..#...#......... */
+ /*01dd:*/ 0x41,0x00, /* .#.....#........ */
+ /*01df:*/ 0x7f,0x00, /* .#######........ */
+ /*01e1:*/ 0x41,0x00, /* .#.....#........ */
+ /*01e3:*/ 0x80,0x80, /* #.......#....... */
+ /*01e5:*/ 0x80,0x80, /* #.......#....... */
+/* --- new character B (66) starting at offset 0x01e7 --- */
+ /*01e7:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01ec:*/ 0xfc, /* ######.. */
+ /*01ed:*/ 0x86, /* #....##. */
+ /*01ee:*/ 0x82, /* #.....#. */
+ /*01ef:*/ 0x82, /* #.....#. */
+ /*01f0:*/ 0x82, /* #.....#. */
+ /*01f1:*/ 0xfc, /* ######.. */
+ /*01f2:*/ 0x82, /* #.....#. */
+ /*01f3:*/ 0x82, /* #.....#. */
+ /*01f4:*/ 0x82, /* #.....#. */
+ /*01f5:*/ 0x82, /* #.....#. */
+ /*01f6:*/ 0xfc, /* ######.. */
+/* --- new character C (67) starting at offset 0x01f7 --- */
+ /*01f7:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01fc:*/ 0x1c, /* ...###.. */
+ /*01fd:*/ 0x63, /* .##...## */
+ /*01fe:*/ 0x41, /* .#.....# */
+ /*01ff:*/ 0x80, /* #....... */
+ /*0200:*/ 0x80, /* #....... */
+ /*0201:*/ 0x80, /* #....... */
+ /*0202:*/ 0x80, /* #....... */
+ /*0203:*/ 0x80, /* #....... */
+ /*0204:*/ 0x41, /* .#.....# */
+ /*0205:*/ 0x63, /* .##...## */
+ /*0206:*/ 0x1c, /* ...###.. */
+/* --- new character D (68) starting at offset 0x0207 --- */
+ /*0207:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*020c:*/ 0xf8, /* #####... */
+ /*020d:*/ 0x86, /* #....##. */
+ /*020e:*/ 0x82, /* #.....#. */
+ /*020f:*/ 0x81, /* #......# */
+ /*0210:*/ 0x81, /* #......# */
+ /*0211:*/ 0x81, /* #......# */
+ /*0212:*/ 0x81, /* #......# */
+ /*0213:*/ 0x81, /* #......# */
+ /*0214:*/ 0x82, /* #.....#. */
+ /*0215:*/ 0x86, /* #....##. */
+ /*0216:*/ 0xf8, /* #####... */
+/* --- new character E (69) starting at offset 0x0217 --- */
+ /*0217:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*021c:*/ 0xfe, /* #######. */
+ /*021d:*/ 0x80, /* #....... */
+ /*021e:*/ 0x80, /* #....... */
+ /*021f:*/ 0x80, /* #....... */
+ /*0220:*/ 0x80, /* #....... */
+ /*0221:*/ 0xfc, /* ######.. */
+ /*0222:*/ 0x80, /* #....... */
+ /*0223:*/ 0x80, /* #....... */
+ /*0224:*/ 0x80, /* #....... */
+ /*0225:*/ 0x80, /* #....... */
+ /*0226:*/ 0xfe, /* #######. */
+/* --- new character F (70) starting at offset 0x0227 --- */
+ /*0227:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*022c:*/ 0xfe, /* #######. */
+ /*022d:*/ 0x80, /* #....... */
+ /*022e:*/ 0x80, /* #....... */
+ /*022f:*/ 0x80, /* #....... */
+ /*0230:*/ 0x80, /* #....... */
+ /*0231:*/ 0xfc, /* ######.. */
+ /*0232:*/ 0x80, /* #....... */
+ /*0233:*/ 0x80, /* #....... */
+ /*0234:*/ 0x80, /* #....... */
+ /*0235:*/ 0x80, /* #....... */
+ /*0236:*/ 0x80, /* #....... */
+/* --- new character G (71) starting at offset 0x0237 --- */
+ /*0237:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*023c:*/ 0x1e,0x00, /* ...####......... */
+ /*023e:*/ 0x61,0x80, /* .##....##....... */
+ /*0240:*/ 0x40,0x80, /* .#......#....... */
+ /*0242:*/ 0x80,0x00, /* #............... */
+ /*0244:*/ 0x80,0x00, /* #............... */
+ /*0246:*/ 0x87,0x80, /* #....####....... */
+ /*0248:*/ 0x80,0x80, /* #.......#....... */
+ /*024a:*/ 0x80,0x80, /* #.......#....... */
+ /*024c:*/ 0x40,0x80, /* .#......#....... */
+ /*024e:*/ 0x63,0x80, /* .##...###....... */
+ /*0250:*/ 0x1c,0x80, /* ...###..#....... */
+/* --- new character H (72) starting at offset 0x0252 --- */
+ /*0252:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0257:*/ 0x81, /* #......# */
+ /*0258:*/ 0x81, /* #......# */
+ /*0259:*/ 0x81, /* #......# */
+ /*025a:*/ 0x81, /* #......# */
+ /*025b:*/ 0x81, /* #......# */
+ /*025c:*/ 0xff, /* ######## */
+ /*025d:*/ 0x81, /* #......# */
+ /*025e:*/ 0x81, /* #......# */
+ /*025f:*/ 0x81, /* #......# */
+ /*0260:*/ 0x81, /* #......# */
+ /*0261:*/ 0x81, /* #......# */
+/* --- new character I (73) starting at offset 0x0262 --- */
+ /*0262:*/ 5, 1, 11, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0267:*/ 0x80, /* #....... */
+ /*0268:*/ 0x80, /* #....... */
+ /*0269:*/ 0x80, /* #....... */
+ /*026a:*/ 0x80, /* #....... */
+ /*026b:*/ 0x80, /* #....... */
+ /*026c:*/ 0x80, /* #....... */
+ /*026d:*/ 0x80, /* #....... */
+ /*026e:*/ 0x80, /* #....... */
+ /*026f:*/ 0x80, /* #....... */
+ /*0270:*/ 0x80, /* #....... */
+ /*0271:*/ 0x80, /* #....... */
+/* --- new character J (74) starting at offset 0x0272 --- */
+ /*0272:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0277:*/ 0x04, /* .....#.. */
+ /*0278:*/ 0x04, /* .....#.. */
+ /*0279:*/ 0x04, /* .....#.. */
+ /*027a:*/ 0x04, /* .....#.. */
+ /*027b:*/ 0x04, /* .....#.. */
+ /*027c:*/ 0x04, /* .....#.. */
+ /*027d:*/ 0x04, /* .....#.. */
+ /*027e:*/ 0x04, /* .....#.. */
+ /*027f:*/ 0x84, /* #....#.. */
+ /*0280:*/ 0x84, /* #....#.. */
+ /*0281:*/ 0x78, /* .####... */
+/* --- new character K (75) starting at offset 0x0282 --- */
+ /*0282:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0287:*/ 0x82, /* #.....#. */
+ /*0288:*/ 0x84, /* #....#.. */
+ /*0289:*/ 0x88, /* #...#... */
+ /*028a:*/ 0x90, /* #..#.... */
+ /*028b:*/ 0xa0, /* #.#..... */
+ /*028c:*/ 0xe0, /* ###..... */
+ /*028d:*/ 0x90, /* #..#.... */
+ /*028e:*/ 0x88, /* #...#... */
+ /*028f:*/ 0x84, /* #....#.. */
+ /*0290:*/ 0x82, /* #.....#. */
+ /*0291:*/ 0x81, /* #......# */
+/* --- new character L (76) starting at offset 0x0292 --- */
+ /*0292:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0297:*/ 0x80, /* #....... */
+ /*0298:*/ 0x80, /* #....... */
+ /*0299:*/ 0x80, /* #....... */
+ /*029a:*/ 0x80, /* #....... */
+ /*029b:*/ 0x80, /* #....... */
+ /*029c:*/ 0x80, /* #....... */
+ /*029d:*/ 0x80, /* #....... */
+ /*029e:*/ 0x80, /* #....... */
+ /*029f:*/ 0x80, /* #....... */
+ /*02a0:*/ 0x80, /* #....... */
+ /*02a1:*/ 0xfc, /* ######.. */
+/* --- new character M (77) starting at offset 0x02a2 --- */
+ /*02a2:*/ 13, 11, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02a7:*/ 0x80,0x20, /* #.........#..... */
+ /*02a9:*/ 0x80,0x20, /* #.........#..... */
+ /*02ab:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02ad:*/ 0xa0,0xa0, /* #.#.....#.#..... */
+ /*02af:*/ 0xa0,0xa0, /* #.#.....#.#..... */
+ /*02b1:*/ 0x91,0x20, /* #..#...#..#..... */
+ /*02b3:*/ 0x91,0x20, /* #..#...#..#..... */
+ /*02b5:*/ 0x8a,0x20, /* #...#.#...#..... */
+ /*02b7:*/ 0x8a,0x20, /* #...#.#...#..... */
+ /*02b9:*/ 0x84,0x20, /* #....#....#..... */
+ /*02bb:*/ 0x84,0x20, /* #....#....#..... */
+/* --- new character N (78) starting at offset 0x02bd --- */
+ /*02bd:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02c2:*/ 0xc1, /* ##.....# */
+ /*02c3:*/ 0xc1, /* ##.....# */
+ /*02c4:*/ 0xa1, /* #.#....# */
+ /*02c5:*/ 0x91, /* #..#...# */
+ /*02c6:*/ 0x91, /* #..#...# */
+ /*02c7:*/ 0x89, /* #...#..# */
+ /*02c8:*/ 0x89, /* #...#..# */
+ /*02c9:*/ 0x85, /* #....#.# */
+ /*02ca:*/ 0x85, /* #....#.# */
+ /*02cb:*/ 0x83, /* #.....## */
+ /*02cc:*/ 0x83, /* #.....## */
+/* --- new character O (79) starting at offset 0x02cd --- */
+ /*02cd:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02d2:*/ 0x1c,0x00, /* ...###.......... */
+ /*02d4:*/ 0x63,0x00, /* .##...##........ */
+ /*02d6:*/ 0x41,0x00, /* .#.....#........ */
+ /*02d8:*/ 0x80,0x80, /* #.......#....... */
+ /*02da:*/ 0x80,0x80, /* #.......#....... */
+ /*02dc:*/ 0x80,0x80, /* #.......#....... */
+ /*02de:*/ 0x80,0x80, /* #.......#....... */
+ /*02e0:*/ 0x80,0x80, /* #.......#....... */
+ /*02e2:*/ 0x41,0x00, /* .#.....#........ */
+ /*02e4:*/ 0x63,0x00, /* .##...##........ */
+ /*02e6:*/ 0x1c,0x00, /* ...###.......... */
+/* --- new character P (80) starting at offset 0x02e8 --- */
+ /*02e8:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02ed:*/ 0xfc, /* ######.. */
+ /*02ee:*/ 0x86, /* #....##. */
+ /*02ef:*/ 0x82, /* #.....#. */
+ /*02f0:*/ 0x82, /* #.....#. */
+ /*02f1:*/ 0x86, /* #....##. */
+ /*02f2:*/ 0xfc, /* ######.. */
+ /*02f3:*/ 0x80, /* #....... */
+ /*02f4:*/ 0x80, /* #....... */
+ /*02f5:*/ 0x80, /* #....... */
+ /*02f6:*/ 0x80, /* #....... */
+ /*02f7:*/ 0x80, /* #....... */
+/* --- new character Q (81) starting at offset 0x02f8 --- */
+ /*02f8:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02fd:*/ 0x1c,0x00, /* ...###.......... */
+ /*02ff:*/ 0x63,0x00, /* .##...##........ */
+ /*0301:*/ 0x41,0x00, /* .#.....#........ */
+ /*0303:*/ 0x80,0x80, /* #.......#....... */
+ /*0305:*/ 0x80,0x80, /* #.......#....... */
+ /*0307:*/ 0x80,0x80, /* #.......#....... */
+ /*0309:*/ 0x88,0x80, /* #...#...#....... */
+ /*030b:*/ 0x84,0x80, /* #....#..#....... */
+ /*030d:*/ 0x43,0x00, /* .#....##........ */
+ /*030f:*/ 0x63,0x00, /* .##...##........ */
+ /*0311:*/ 0x1c,0x80, /* ...###..#....... */
+/* --- new character R (82) starting at offset 0x0313 --- */
+ /*0313:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0318:*/ 0xfc, /* ######.. */
+ /*0319:*/ 0x86, /* #....##. */
+ /*031a:*/ 0x82, /* #.....#. */
+ /*031b:*/ 0x82, /* #.....#. */
+ /*031c:*/ 0x84, /* #....#.. */
+ /*031d:*/ 0xf8, /* #####... */
+ /*031e:*/ 0x84, /* #....#.. */
+ /*031f:*/ 0x82, /* #.....#. */
+ /*0320:*/ 0x82, /* #.....#. */
+ /*0321:*/ 0x82, /* #.....#. */
+ /*0322:*/ 0x82, /* #.....#. */
+/* --- new character S (83) starting at offset 0x0323 --- */
+ /*0323:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0328:*/ 0x38, /* ..###... */
+ /*0329:*/ 0xc6, /* ##...##. */
+ /*032a:*/ 0x82, /* #.....#. */
+ /*032b:*/ 0x80, /* #....... */
+ /*032c:*/ 0x60, /* .##..... */
+ /*032d:*/ 0x18, /* ...##... */
+ /*032e:*/ 0x06, /* .....##. */
+ /*032f:*/ 0x02, /* ......#. */
+ /*0330:*/ 0x82, /* #.....#. */
+ /*0331:*/ 0xc6, /* ##...##. */
+ /*0332:*/ 0x38, /* ..###... */
+/* --- new character T (84) starting at offset 0x0333 --- */
+ /*0333:*/ 9, 9, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0338:*/ 0xff,0x80, /* #########....... */
+ /*033a:*/ 0x08,0x00, /* ....#........... */
+ /*033c:*/ 0x08,0x00, /* ....#........... */
+ /*033e:*/ 0x08,0x00, /* ....#........... */
+ /*0340:*/ 0x08,0x00, /* ....#........... */
+ /*0342:*/ 0x08,0x00, /* ....#........... */
+ /*0344:*/ 0x08,0x00, /* ....#........... */
+ /*0346:*/ 0x08,0x00, /* ....#........... */
+ /*0348:*/ 0x08,0x00, /* ....#........... */
+ /*034a:*/ 0x08,0x00, /* ....#........... */
+ /*034c:*/ 0x08,0x00, /* ....#........... */
+/* --- new character U (85) starting at offset 0x034e --- */
+ /*034e:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0353:*/ 0x81, /* #......# */
+ /*0354:*/ 0x81, /* #......# */
+ /*0355:*/ 0x81, /* #......# */
+ /*0356:*/ 0x81, /* #......# */
+ /*0357:*/ 0x81, /* #......# */
+ /*0358:*/ 0x81, /* #......# */
+ /*0359:*/ 0x81, /* #......# */
+ /*035a:*/ 0x81, /* #......# */
+ /*035b:*/ 0x81, /* #......# */
+ /*035c:*/ 0x42, /* .#....#. */
+ /*035d:*/ 0x3c, /* ..####.. */
+/* --- new character V (86) starting at offset 0x035e --- */
+ /*035e:*/ 11, 9, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0363:*/ 0x80,0x80, /* #.......#....... */
+ /*0365:*/ 0x80,0x80, /* #.......#....... */
+ /*0367:*/ 0x41,0x00, /* .#.....#........ */
+ /*0369:*/ 0x41,0x00, /* .#.....#........ */
+ /*036b:*/ 0x22,0x00, /* ..#...#......... */
+ /*036d:*/ 0x22,0x00, /* ..#...#......... */
+ /*036f:*/ 0x22,0x00, /* ..#...#......... */
+ /*0371:*/ 0x14,0x00, /* ...#.#.......... */
+ /*0373:*/ 0x14,0x00, /* ...#.#.......... */
+ /*0375:*/ 0x08,0x00, /* ....#........... */
+ /*0377:*/ 0x08,0x00, /* ....#........... */
+/* --- new character W (87) starting at offset 0x0379 --- */
+ /*0379:*/ 15, 13, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*037e:*/ 0x82,0x08, /* #.....#.....#... */
+ /*0380:*/ 0x82,0x08, /* #.....#.....#... */
+ /*0382:*/ 0x85,0x08, /* #....#.#....#... */
+ /*0384:*/ 0x45,0x10, /* .#...#.#...#.... */
+ /*0386:*/ 0x45,0x10, /* .#...#.#...#.... */
+ /*0388:*/ 0x45,0x10, /* .#...#.#...#.... */
+ /*038a:*/ 0x28,0xa0, /* ..#.#...#.#..... */
+ /*038c:*/ 0x28,0xa0, /* ..#.#...#.#..... */
+ /*038e:*/ 0x28,0xa0, /* ..#.#...#.#..... */
+ /*0390:*/ 0x10,0x40, /* ...#.....#...... */
+ /*0392:*/ 0x10,0x40, /* ...#.....#...... */
+/* --- new character X (88) starting at offset 0x0394 --- */
+ /*0394:*/ 10, 8, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0399:*/ 0x81, /* #......# */
+ /*039a:*/ 0x81, /* #......# */
+ /*039b:*/ 0x42, /* .#....#. */
+ /*039c:*/ 0x24, /* ..#..#.. */
+ /*039d:*/ 0x18, /* ...##... */
+ /*039e:*/ 0x18, /* ...##... */
+ /*039f:*/ 0x24, /* ..#..#.. */
+ /*03a0:*/ 0x42, /* .#....#. */
+ /*03a1:*/ 0x42, /* .#....#. */
+ /*03a2:*/ 0x81, /* #......# */
+ /*03a3:*/ 0x81, /* #......# */
+/* --- new character Y (89) starting at offset 0x03a4 --- */
+ /*03a4:*/ 9, 9, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03a9:*/ 0x80,0x80, /* #.......#....... */
+ /*03ab:*/ 0x41,0x00, /* .#.....#........ */
+ /*03ad:*/ 0x41,0x00, /* .#.....#........ */
+ /*03af:*/ 0x22,0x00, /* ..#...#......... */
+ /*03b1:*/ 0x22,0x00, /* ..#...#......... */
+ /*03b3:*/ 0x14,0x00, /* ...#.#.......... */
+ /*03b5:*/ 0x08,0x00, /* ....#........... */
+ /*03b7:*/ 0x08,0x00, /* ....#........... */
+ /*03b9:*/ 0x08,0x00, /* ....#........... */
+ /*03bb:*/ 0x08,0x00, /* ....#........... */
+ /*03bd:*/ 0x08,0x00, /* ....#........... */
+/* --- new character Z (90) starting at offset 0x03bf --- */
+ /*03bf:*/ 9, 7, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*03c4:*/ 0xfe, /* #######. */
+ /*03c5:*/ 0x02, /* ......#. */
+ /*03c6:*/ 0x04, /* .....#.. */
+ /*03c7:*/ 0x08, /* ....#... */
+ /*03c8:*/ 0x18, /* ...##... */
+ /*03c9:*/ 0x10, /* ...#.... */
+ /*03ca:*/ 0x20, /* ..#..... */
+ /*03cb:*/ 0x60, /* .##..... */
+ /*03cc:*/ 0x40, /* .#...... */
+ /*03cd:*/ 0x80, /* #....... */
+ /*03ce:*/ 0xfe, /* #######. */
+/* --- new character bracketleft (91) starting at offset 0x03cf --- */
+ /*03cf:*/ 4, 3, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*03d4:*/ 0xe0, /* ###..... */
+ /*03d5:*/ 0x80, /* #....... */
+ /*03d6:*/ 0x80, /* #....... */
+ /*03d7:*/ 0x80, /* #....... */
+ /*03d8:*/ 0x80, /* #....... */
+ /*03d9:*/ 0x80, /* #....... */
+ /*03da:*/ 0x80, /* #....... */
+ /*03db:*/ 0x80, /* #....... */
+ /*03dc:*/ 0x80, /* #....... */
+ /*03dd:*/ 0x80, /* #....... */
+ /*03de:*/ 0x80, /* #....... */
+ /*03df:*/ 0x80, /* #....... */
+ /*03e0:*/ 0x80, /* #....... */
+ /*03e1:*/ 0xe0, /* ###..... */
+/* --- new character backslash (92) starting at offset 0x03e2 --- */
+ /*03e2:*/ 4, 4, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*03e7:*/ 0x80, /* #....... */
+ /*03e8:*/ 0x80, /* #....... */
+ /*03e9:*/ 0x40, /* .#...... */
+ /*03ea:*/ 0x40, /* .#...... */
+ /*03eb:*/ 0x40, /* .#...... */
+ /*03ec:*/ 0x20, /* ..#..... */
+ /*03ed:*/ 0x20, /* ..#..... */
+ /*03ee:*/ 0x20, /* ..#..... */
+ /*03ef:*/ 0x10, /* ...#.... */
+ /*03f0:*/ 0x10, /* ...#.... */
+ /*03f1:*/ 0x10, /* ...#.... */
+/* --- new character bracketright (93) starting at offset 0x03f2 --- */
+ /*03f2:*/ 4, 3, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*03f7:*/ 0xe0, /* ###..... */
+ /*03f8:*/ 0x20, /* ..#..... */
+ /*03f9:*/ 0x20, /* ..#..... */
+ /*03fa:*/ 0x20, /* ..#..... */
+ /*03fb:*/ 0x20, /* ..#..... */
+ /*03fc:*/ 0x20, /* ..#..... */
+ /*03fd:*/ 0x20, /* ..#..... */
+ /*03fe:*/ 0x20, /* ..#..... */
+ /*03ff:*/ 0x20, /* ..#..... */
+ /*0400:*/ 0x20, /* ..#..... */
+ /*0401:*/ 0x20, /* ..#..... */
+ /*0402:*/ 0x20, /* ..#..... */
+ /*0403:*/ 0x20, /* ..#..... */
+ /*0404:*/ 0xe0, /* ###..... */
+/* --- new character asciicircum (94) starting at offset 0x0405 --- */
+ /*0405:*/ 7, 7, 4, 0, 6, /* width and bbox (w,h,x,y) */
+ /*040a:*/ 0x10, /* ...#.... */
+ /*040b:*/ 0x28, /* ..#.#... */
+ /*040c:*/ 0x44, /* .#...#.. */
+ /*040d:*/ 0x82, /* #.....#. */
+/* --- new character underscore (95) starting at offset 0x040e --- */
+ /*040e:*/ 8, 8, 1, 0, -3, /* width and bbox (w,h,x,y) */
+ /*0413:*/ 0xff, /* ######## */
+/* --- new character grave (96) starting at offset 0x0414 --- */
+ /*0414:*/ 5, 2, 2, 1, 9, /* width and bbox (w,h,x,y) */
+ /*0419:*/ 0x80, /* #....... */
+ /*041a:*/ 0x40, /* .#...... */
+/* --- new character a (97) starting at offset 0x041b --- */
+ /*041b:*/ 8, 7, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0420:*/ 0x78, /* .####... */
+ /*0421:*/ 0xcc, /* ##..##.. */
+ /*0422:*/ 0x04, /* .....#.. */
+ /*0423:*/ 0x7c, /* .#####.. */
+ /*0424:*/ 0xc4, /* ##...#.. */
+ /*0425:*/ 0x84, /* #....#.. */
+ /*0426:*/ 0xcc, /* ##..##.. */
+ /*0427:*/ 0x76, /* .###.##. */
+/* --- new character b (98) starting at offset 0x0428 --- */
+ /*0428:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*042d:*/ 0x80, /* #....... */
+ /*042e:*/ 0x80, /* #....... */
+ /*042f:*/ 0x80, /* #....... */
+ /*0430:*/ 0xb8, /* #.###... */
+ /*0431:*/ 0xcc, /* ##..##.. */
+ /*0432:*/ 0x84, /* #....#.. */
+ /*0433:*/ 0x84, /* #....#.. */
+ /*0434:*/ 0x84, /* #....#.. */
+ /*0435:*/ 0x84, /* #....#.. */
+ /*0436:*/ 0xcc, /* ##..##.. */
+ /*0437:*/ 0xb8, /* #.###... */
+/* --- new character c (99) starting at offset 0x0438 --- */
+ /*0438:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*043d:*/ 0x78, /* .####... */
+ /*043e:*/ 0xcc, /* ##..##.. */
+ /*043f:*/ 0x80, /* #....... */
+ /*0440:*/ 0x80, /* #....... */
+ /*0441:*/ 0x80, /* #....... */
+ /*0442:*/ 0x84, /* #....#.. */
+ /*0443:*/ 0xcc, /* ##..##.. */
+ /*0444:*/ 0x78, /* .####... */
+/* --- new character d (100) starting at offset 0x0445 --- */
+ /*0445:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*044a:*/ 0x04, /* .....#.. */
+ /*044b:*/ 0x04, /* .....#.. */
+ /*044c:*/ 0x04, /* .....#.. */
+ /*044d:*/ 0x74, /* .###.#.. */
+ /*044e:*/ 0xcc, /* ##..##.. */
+ /*044f:*/ 0x84, /* #....#.. */
+ /*0450:*/ 0x84, /* #....#.. */
+ /*0451:*/ 0x84, /* #....#.. */
+ /*0452:*/ 0x84, /* #....#.. */
+ /*0453:*/ 0xcc, /* ##..##.. */
+ /*0454:*/ 0x74, /* .###.#.. */
+/* --- new character e (101) starting at offset 0x0455 --- */
+ /*0455:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*045a:*/ 0x78, /* .####... */
+ /*045b:*/ 0xcc, /* ##..##.. */
+ /*045c:*/ 0x84, /* #....#.. */
+ /*045d:*/ 0xfc, /* ######.. */
+ /*045e:*/ 0x80, /* #....... */
+ /*045f:*/ 0x80, /* #....... */
+ /*0460:*/ 0xcc, /* ##..##.. */
+ /*0461:*/ 0x78, /* .####... */
+/* --- new character f (102) starting at offset 0x0462 --- */
+ /*0462:*/ 3, 4, 11, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0467:*/ 0x30, /* ..##.... */
+ /*0468:*/ 0x40, /* .#...... */
+ /*0469:*/ 0x40, /* .#...... */
+ /*046a:*/ 0xe0, /* ###..... */
+ /*046b:*/ 0x40, /* .#...... */
+ /*046c:*/ 0x40, /* .#...... */
+ /*046d:*/ 0x40, /* .#...... */
+ /*046e:*/ 0x40, /* .#...... */
+ /*046f:*/ 0x40, /* .#...... */
+ /*0470:*/ 0x40, /* .#...... */
+ /*0471:*/ 0x40, /* .#...... */
+/* --- new character g (103) starting at offset 0x0472 --- */
+ /*0472:*/ 8, 6, 11, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0477:*/ 0x74, /* .###.#.. */
+ /*0478:*/ 0xcc, /* ##..##.. */
+ /*0479:*/ 0x84, /* #....#.. */
+ /*047a:*/ 0x84, /* #....#.. */
+ /*047b:*/ 0x84, /* #....#.. */
+ /*047c:*/ 0x84, /* #....#.. */
+ /*047d:*/ 0xcc, /* ##..##.. */
+ /*047e:*/ 0x74, /* .###.#.. */
+ /*047f:*/ 0x04, /* .....#.. */
+ /*0480:*/ 0xcc, /* ##..##.. */
+ /*0481:*/ 0x78, /* .####... */
+/* --- new character h (104) starting at offset 0x0482 --- */
+ /*0482:*/ 8, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0487:*/ 0x80, /* #....... */
+ /*0488:*/ 0x80, /* #....... */
+ /*0489:*/ 0x80, /* #....... */
+ /*048a:*/ 0xb8, /* #.###... */
+ /*048b:*/ 0xcc, /* ##..##.. */
+ /*048c:*/ 0x84, /* #....#.. */
+ /*048d:*/ 0x84, /* #....#.. */
+ /*048e:*/ 0x84, /* #....#.. */
+ /*048f:*/ 0x84, /* #....#.. */
+ /*0490:*/ 0x84, /* #....#.. */
+ /*0491:*/ 0x84, /* #....#.. */
+/* --- new character i (105) starting at offset 0x0492 --- */
+ /*0492:*/ 3, 1, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0497:*/ 0x80, /* #....... */
+ /*0498:*/ 0x80, /* #....... */
+ /*0499:*/ 0x00, /* ........ */
+ /*049a:*/ 0x80, /* #....... */
+ /*049b:*/ 0x80, /* #....... */
+ /*049c:*/ 0x80, /* #....... */
+ /*049d:*/ 0x80, /* #....... */
+ /*049e:*/ 0x80, /* #....... */
+ /*049f:*/ 0x80, /* #....... */
+ /*04a0:*/ 0x80, /* #....... */
+ /*04a1:*/ 0x80, /* #....... */
+/* --- new character j (106) starting at offset 0x04a2 --- */
+ /*04a2:*/ 3, 3, 14, -1, -3, /* width and bbox (w,h,x,y) */
+ /*04a7:*/ 0x20, /* ..#..... */
+ /*04a8:*/ 0x20, /* ..#..... */
+ /*04a9:*/ 0x00, /* ........ */
+ /*04aa:*/ 0x20, /* ..#..... */
+ /*04ab:*/ 0x20, /* ..#..... */
+ /*04ac:*/ 0x20, /* ..#..... */
+ /*04ad:*/ 0x20, /* ..#..... */
+ /*04ae:*/ 0x20, /* ..#..... */
+ /*04af:*/ 0x20, /* ..#..... */
+ /*04b0:*/ 0x20, /* ..#..... */
+ /*04b1:*/ 0x20, /* ..#..... */
+ /*04b2:*/ 0x20, /* ..#..... */
+ /*04b3:*/ 0x20, /* ..#..... */
+ /*04b4:*/ 0xc0, /* ##...... */
+/* --- new character k (107) starting at offset 0x04b5 --- */
+ /*04b5:*/ 7, 6, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04ba:*/ 0x80, /* #....... */
+ /*04bb:*/ 0x80, /* #....... */
+ /*04bc:*/ 0x80, /* #....... */
+ /*04bd:*/ 0x88, /* #...#... */
+ /*04be:*/ 0x90, /* #..#.... */
+ /*04bf:*/ 0xa0, /* #.#..... */
+ /*04c0:*/ 0xc0, /* ##...... */
+ /*04c1:*/ 0xa0, /* #.#..... */
+ /*04c2:*/ 0x90, /* #..#.... */
+ /*04c3:*/ 0x88, /* #...#... */
+ /*04c4:*/ 0x84, /* #....#.. */
+/* --- new character l (108) starting at offset 0x04c5 --- */
+ /*04c5:*/ 3, 1, 11, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04ca:*/ 0x80, /* #....... */
+ /*04cb:*/ 0x80, /* #....... */
+ /*04cc:*/ 0x80, /* #....... */
+ /*04cd:*/ 0x80, /* #....... */
+ /*04ce:*/ 0x80, /* #....... */
+ /*04cf:*/ 0x80, /* #....... */
+ /*04d0:*/ 0x80, /* #....... */
+ /*04d1:*/ 0x80, /* #....... */
+ /*04d2:*/ 0x80, /* #....... */
+ /*04d3:*/ 0x80, /* #....... */
+ /*04d4:*/ 0x80, /* #....... */
+/* --- new character m (109) starting at offset 0x04d5 --- */
+ /*04d5:*/ 11, 9, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04da:*/ 0xb3,0x00, /* #.##..##........ */
+ /*04dc:*/ 0xcc,0x80, /* ##..##..#....... */
+ /*04de:*/ 0x88,0x80, /* #...#...#....... */
+ /*04e0:*/ 0x88,0x80, /* #...#...#....... */
+ /*04e2:*/ 0x88,0x80, /* #...#...#....... */
+ /*04e4:*/ 0x88,0x80, /* #...#...#....... */
+ /*04e6:*/ 0x88,0x80, /* #...#...#....... */
+ /*04e8:*/ 0x88,0x80, /* #...#...#....... */
+/* --- new character n (110) starting at offset 0x04ea --- */
+ /*04ea:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04ef:*/ 0xb8, /* #.###... */
+ /*04f0:*/ 0xcc, /* ##..##.. */
+ /*04f1:*/ 0x84, /* #....#.. */
+ /*04f2:*/ 0x84, /* #....#.. */
+ /*04f3:*/ 0x84, /* #....#.. */
+ /*04f4:*/ 0x84, /* #....#.. */
+ /*04f5:*/ 0x84, /* #....#.. */
+ /*04f6:*/ 0x84, /* #....#.. */
+/* --- new character o (111) starting at offset 0x04f7 --- */
+ /*04f7:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04fc:*/ 0x78, /* .####... */
+ /*04fd:*/ 0xcc, /* ##..##.. */
+ /*04fe:*/ 0x84, /* #....#.. */
+ /*04ff:*/ 0x84, /* #....#.. */
+ /*0500:*/ 0x84, /* #....#.. */
+ /*0501:*/ 0x84, /* #....#.. */
+ /*0502:*/ 0xcc, /* ##..##.. */
+ /*0503:*/ 0x78, /* .####... */
+/* --- new character p (112) starting at offset 0x0504 --- */
+ /*0504:*/ 8, 6, 11, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0509:*/ 0xb8, /* #.###... */
+ /*050a:*/ 0xcc, /* ##..##.. */
+ /*050b:*/ 0x84, /* #....#.. */
+ /*050c:*/ 0x84, /* #....#.. */
+ /*050d:*/ 0x84, /* #....#.. */
+ /*050e:*/ 0x84, /* #....#.. */
+ /*050f:*/ 0xcc, /* ##..##.. */
+ /*0510:*/ 0xb8, /* #.###... */
+ /*0511:*/ 0x80, /* #....... */
+ /*0512:*/ 0x80, /* #....... */
+ /*0513:*/ 0x80, /* #....... */
+/* --- new character q (113) starting at offset 0x0514 --- */
+ /*0514:*/ 8, 6, 11, 1, -3, /* width and bbox (w,h,x,y) */
+ /*0519:*/ 0x74, /* .###.#.. */
+ /*051a:*/ 0xcc, /* ##..##.. */
+ /*051b:*/ 0x84, /* #....#.. */
+ /*051c:*/ 0x84, /* #....#.. */
+ /*051d:*/ 0x84, /* #....#.. */
+ /*051e:*/ 0x84, /* #....#.. */
+ /*051f:*/ 0xcc, /* ##..##.. */
+ /*0520:*/ 0x74, /* .###.#.. */
+ /*0521:*/ 0x04, /* .....#.. */
+ /*0522:*/ 0x04, /* .....#.. */
+ /*0523:*/ 0x04, /* .....#.. */
+/* --- new character r (114) starting at offset 0x0524 --- */
+ /*0524:*/ 5, 4, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0529:*/ 0xb0, /* #.##.... */
+ /*052a:*/ 0xc0, /* ##...... */
+ /*052b:*/ 0x80, /* #....... */
+ /*052c:*/ 0x80, /* #....... */
+ /*052d:*/ 0x80, /* #....... */
+ /*052e:*/ 0x80, /* #....... */
+ /*052f:*/ 0x80, /* #....... */
+ /*0530:*/ 0x80, /* #....... */
+/* --- new character s (115) starting at offset 0x0531 --- */
+ /*0531:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0536:*/ 0x78, /* .####... */
+ /*0537:*/ 0x84, /* #....#.. */
+ /*0538:*/ 0x80, /* #....... */
+ /*0539:*/ 0x78, /* .####... */
+ /*053a:*/ 0x0c, /* ....##.. */
+ /*053b:*/ 0x04, /* .....#.. */
+ /*053c:*/ 0x84, /* #....#.. */
+ /*053d:*/ 0x78, /* .####... */
+/* --- new character t (116) starting at offset 0x053e --- */
+ /*053e:*/ 4, 4, 10, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0543:*/ 0x40, /* .#...... */
+ /*0544:*/ 0x40, /* .#...... */
+ /*0545:*/ 0xf0, /* ####.... */
+ /*0546:*/ 0x40, /* .#...... */
+ /*0547:*/ 0x40, /* .#...... */
+ /*0548:*/ 0x40, /* .#...... */
+ /*0549:*/ 0x40, /* .#...... */
+ /*054a:*/ 0x40, /* .#...... */
+ /*054b:*/ 0x40, /* .#...... */
+ /*054c:*/ 0x30, /* ..##.... */
+/* --- new character u (117) starting at offset 0x054d --- */
+ /*054d:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0552:*/ 0x84, /* #....#.. */
+ /*0553:*/ 0x84, /* #....#.. */
+ /*0554:*/ 0x84, /* #....#.. */
+ /*0555:*/ 0x84, /* #....#.. */
+ /*0556:*/ 0x84, /* #....#.. */
+ /*0557:*/ 0x84, /* #....#.. */
+ /*0558:*/ 0xcc, /* ##..##.. */
+ /*0559:*/ 0x74, /* .###.#.. */
+/* --- new character v (118) starting at offset 0x055a --- */
+ /*055a:*/ 8, 6, 8, 1, 0, /* width and bbox (w,h,x,y) */
+ /*055f:*/ 0x84, /* #....#.. */
+ /*0560:*/ 0x84, /* #....#.. */
+ /*0561:*/ 0x84, /* #....#.. */
+ /*0562:*/ 0x48, /* .#..#... */
+ /*0563:*/ 0x48, /* .#..#... */
+ /*0564:*/ 0x48, /* .#..#... */
+ /*0565:*/ 0x30, /* ..##.... */
+ /*0566:*/ 0x30, /* ..##.... */
+/* --- new character w (119) starting at offset 0x0567 --- */
+ /*0567:*/ 10, 9, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*056c:*/ 0x88,0x80, /* #...#...#....... */
+ /*056e:*/ 0x88,0x80, /* #...#...#....... */
+ /*0570:*/ 0x88,0x80, /* #...#...#....... */
+ /*0572:*/ 0x49,0x00, /* .#..#..#........ */
+ /*0574:*/ 0x49,0x00, /* .#..#..#........ */
+ /*0576:*/ 0x55,0x00, /* .#.#.#.#........ */
+ /*0578:*/ 0x22,0x00, /* ..#...#......... */
+ /*057a:*/ 0x22,0x00, /* ..#...#......... */
+/* --- new character x (120) starting at offset 0x057c --- */
+ /*057c:*/ 7, 7, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0581:*/ 0xc6, /* ##...##. */
+ /*0582:*/ 0x44, /* .#...#.. */
+ /*0583:*/ 0x28, /* ..#.#... */
+ /*0584:*/ 0x10, /* ...#.... */
+ /*0585:*/ 0x10, /* ...#.... */
+ /*0586:*/ 0x28, /* ..#.#... */
+ /*0587:*/ 0x44, /* .#...#.. */
+ /*0588:*/ 0xc6, /* ##...##. */
+/* --- new character y (121) starting at offset 0x0589 --- */
+ /*0589:*/ 7, 7, 11, 0, -3, /* width and bbox (w,h,x,y) */
+ /*058e:*/ 0x82, /* #.....#. */
+ /*058f:*/ 0x82, /* #.....#. */
+ /*0590:*/ 0x44, /* .#...#.. */
+ /*0591:*/ 0x44, /* .#...#.. */
+ /*0592:*/ 0x24, /* ..#..#.. */
+ /*0593:*/ 0x28, /* ..#.#... */
+ /*0594:*/ 0x18, /* ...##... */
+ /*0595:*/ 0x10, /* ...#.... */
+ /*0596:*/ 0x10, /* ...#.... */
+ /*0597:*/ 0x30, /* ..##.... */
+ /*0598:*/ 0x60, /* .##..... */
+/* --- new character z (122) starting at offset 0x0599 --- */
+ /*0599:*/ 7, 6, 8, 0, 0, /* width and bbox (w,h,x,y) */
+ /*059e:*/ 0xfc, /* ######.. */
+ /*059f:*/ 0x04, /* .....#.. */
+ /*05a0:*/ 0x08, /* ....#... */
+ /*05a1:*/ 0x10, /* ...#.... */
+ /*05a2:*/ 0x20, /* ..#..... */
+ /*05a3:*/ 0x40, /* .#...... */
+ /*05a4:*/ 0x80, /* #....... */
+ /*05a5:*/ 0xfc, /* ######.. */
+/* --- new character braceleft (123) starting at offset 0x05a6 --- */
+ /*05a6:*/ 5, 5, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*05ab:*/ 0x18, /* ...##... */
+ /*05ac:*/ 0x20, /* ..#..... */
+ /*05ad:*/ 0x20, /* ..#..... */
+ /*05ae:*/ 0x20, /* ..#..... */
+ /*05af:*/ 0x20, /* ..#..... */
+ /*05b0:*/ 0x40, /* .#...... */
+ /*05b1:*/ 0x80, /* #....... */
+ /*05b2:*/ 0x40, /* .#...... */
+ /*05b3:*/ 0x20, /* ..#..... */
+ /*05b4:*/ 0x20, /* ..#..... */
+ /*05b5:*/ 0x20, /* ..#..... */
+ /*05b6:*/ 0x20, /* ..#..... */
+ /*05b7:*/ 0x20, /* ..#..... */
+ /*05b8:*/ 0x18, /* ...##... */
+/* --- new character bar (124) starting at offset 0x05b9 --- */
+ /*05b9:*/ 3, 1, 14, 1, -3, /* width and bbox (w,h,x,y) */
+ /*05be:*/ 0x80, /* #....... */
+ /*05bf:*/ 0x80, /* #....... */
+ /*05c0:*/ 0x80, /* #....... */
+ /*05c1:*/ 0x80, /* #....... */
+ /*05c2:*/ 0x80, /* #....... */
+ /*05c3:*/ 0x80, /* #....... */
+ /*05c4:*/ 0x80, /* #....... */
+ /*05c5:*/ 0x80, /* #....... */
+ /*05c6:*/ 0x80, /* #....... */
+ /*05c7:*/ 0x80, /* #....... */
+ /*05c8:*/ 0x80, /* #....... */
+ /*05c9:*/ 0x80, /* #....... */
+ /*05ca:*/ 0x80, /* #....... */
+ /*05cb:*/ 0x80, /* #....... */
+/* --- new character braceright (125) starting at offset 0x05cc --- */
+ /*05cc:*/ 5, 5, 14, 0, -3, /* width and bbox (w,h,x,y) */
+ /*05d1:*/ 0xc0, /* ##...... */
+ /*05d2:*/ 0x20, /* ..#..... */
+ /*05d3:*/ 0x20, /* ..#..... */
+ /*05d4:*/ 0x20, /* ..#..... */
+ /*05d5:*/ 0x20, /* ..#..... */
+ /*05d6:*/ 0x10, /* ...#.... */
+ /*05d7:*/ 0x08, /* ....#... */
+ /*05d8:*/ 0x10, /* ...#.... */
+ /*05d9:*/ 0x20, /* ..#..... */
+ /*05da:*/ 0x20, /* ..#..... */
+ /*05db:*/ 0x20, /* ..#..... */
+ /*05dc:*/ 0x20, /* ..#..... */
+ /*05dd:*/ 0x20, /* ..#..... */
+ /*05de:*/ 0xc0, /* ##...... */
+/* --- new character asciitilde (126) starting at offset 0x05df --- */
+ /*05df:*/ 8, 6, 3, 1, 3, /* width and bbox (w,h,x,y) */
+ /*05e4:*/ 0x64, /* .##..#.. */
+ /*05e5:*/ 0xb4, /* #.##.#.. */
+ /*05e6:*/ 0x98, /* #..##... */
+};
+static const uint16_t font_helvR14_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x0016 /* quotedbl */,
+ 0x001e /* numbersign */,
+ 0x002d /* dollar */,
+ 0x0040 /* percent */,
+ 0x0059 /* ampersand */,
+ 0x0068 /* quotesingle */,
+ 0x0070 /* parenleft */,
+ 0x0083 /* parenright */,
+ 0x0096 /* asterisk */,
+ 0x009f /* plus */,
+ 0x00ab /* comma */,
+ 0x00b4 /* hyphen */,
+ 0x00ba /* period */,
+ 0x00c1 /* slash */,
+ 0x00d1 /* zero */,
+ 0x00e0 /* one */,
+ 0x00ef /* two */,
+ 0x00fe /* three */,
+ 0x010d /* four */,
+ 0x011c /* five */,
+ 0x012b /* six */,
+ 0x013a /* seven */,
+ 0x0149 /* eight */,
+ 0x0158 /* nine */,
+ 0x0167 /* colon */,
+ 0x0174 /* semicolon */,
+ 0x0183 /* less */,
+ 0x018d /* equal */,
+ 0x0195 /* greater */,
+ 0x019f /* question */,
+ 0x01af /* at */,
+ 0x01cc /* A */,
+ 0x01e7 /* B */,
+ 0x01f7 /* C */,
+ 0x0207 /* D */,
+ 0x0217 /* E */,
+ 0x0227 /* F */,
+ 0x0237 /* G */,
+ 0x0252 /* H */,
+ 0x0262 /* I */,
+ 0x0272 /* J */,
+ 0x0282 /* K */,
+ 0x0292 /* L */,
+ 0x02a2 /* M */,
+ 0x02bd /* N */,
+ 0x02cd /* O */,
+ 0x02e8 /* P */,
+ 0x02f8 /* Q */,
+ 0x0313 /* R */,
+ 0x0323 /* S */,
+ 0x0333 /* T */,
+ 0x034e /* U */,
+ 0x035e /* V */,
+ 0x0379 /* W */,
+ 0x0394 /* X */,
+ 0x03a4 /* Y */,
+ 0x03bf /* Z */,
+ 0x03cf /* bracketleft */,
+ 0x03e2 /* backslash */,
+ 0x03f2 /* bracketright */,
+ 0x0405 /* asciicircum */,
+ 0x040e /* underscore */,
+ 0x0414 /* grave */,
+ 0x041b /* a */,
+ 0x0428 /* b */,
+ 0x0438 /* c */,
+ 0x0445 /* d */,
+ 0x0455 /* e */,
+ 0x0462 /* f */,
+ 0x0472 /* g */,
+ 0x0482 /* h */,
+ 0x0492 /* i */,
+ 0x04a2 /* j */,
+ 0x04b5 /* k */,
+ 0x04c5 /* l */,
+ 0x04d5 /* m */,
+ 0x04ea /* n */,
+ 0x04f7 /* o */,
+ 0x0504 /* p */,
+ 0x0514 /* q */,
+ 0x0524 /* r */,
+ 0x0531 /* s */,
+ 0x053e /* t */,
+ 0x054d /* u */,
+ 0x055a /* v */,
+ 0x0567 /* w */,
+ 0x057c /* x */,
+ 0x0589 /* y */,
+ 0x0599 /* z */,
+ 0x05a6 /* braceleft */,
+ 0x05b9 /* bar */,
+ 0x05cc /* braceright */,
+ 0x05df /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_helvR14 = {
+ .height = 16,
+ .ascent = 13,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_helvR14_data,
+ .charoffs = font_helvR14_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/fb/helvR24.c b/Src/osmolib/src/target/firmware/fb/helvR24.c
new file mode 100644
index 0000000..18ff0c4
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/fb/helvR24.c
@@ -0,0 +1,1870 @@
+#include <fb/font.h>
+static const uint8_t font_helvR24_data[] = {
+/* --- new character space (32) starting at offset 0x0000 --- */
+ /*0000:*/ 6, 1, 1, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0005:*/ 0x00, /* ........ */
+/* --- new character exclam (33) starting at offset 0x0006 --- */
+ /*0006:*/ 6, 2, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*000b:*/ 0xc0, /* ##...... */
+ /*000c:*/ 0xc0, /* ##...... */
+ /*000d:*/ 0xc0, /* ##...... */
+ /*000e:*/ 0xc0, /* ##...... */
+ /*000f:*/ 0xc0, /* ##...... */
+ /*0010:*/ 0xc0, /* ##...... */
+ /*0011:*/ 0xc0, /* ##...... */
+ /*0012:*/ 0xc0, /* ##...... */
+ /*0013:*/ 0xc0, /* ##...... */
+ /*0014:*/ 0xc0, /* ##...... */
+ /*0015:*/ 0xc0, /* ##...... */
+ /*0016:*/ 0xc0, /* ##...... */
+ /*0017:*/ 0x80, /* #....... */
+ /*0018:*/ 0x80, /* #....... */
+ /*0019:*/ 0x00, /* ........ */
+ /*001a:*/ 0x00, /* ........ */
+ /*001b:*/ 0xc0, /* ##...... */
+ /*001c:*/ 0xc0, /* ##...... */
+ /*001d:*/ 0xc0, /* ##...... */
+/* --- new character quotedbl (34) starting at offset 0x001e --- */
+ /*001e:*/ 8, 6, 6, 1, 13, /* width and bbox (w,h,x,y) */
+ /*0023:*/ 0xcc, /* ##..##.. */
+ /*0024:*/ 0xcc, /* ##..##.. */
+ /*0025:*/ 0xcc, /* ##..##.. */
+ /*0026:*/ 0xcc, /* ##..##.. */
+ /*0027:*/ 0xcc, /* ##..##.. */
+ /*0028:*/ 0x44, /* .#...#.. */
+/* --- new character numbersign (35) starting at offset 0x0029 --- */
+ /*0029:*/ 14, 11, 17, 2, 0, /* width and bbox (w,h,x,y) */
+ /*002e:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0030:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0032:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0034:*/ 0x19,0x80, /* ...##..##....... */
+ /*0036:*/ 0xff,0xe0, /* ###########..... */
+ /*0038:*/ 0xff,0xe0, /* ###########..... */
+ /*003a:*/ 0x19,0x80, /* ...##..##....... */
+ /*003c:*/ 0x19,0x80, /* ...##..##....... */
+ /*003e:*/ 0x33,0x00, /* ..##..##........ */
+ /*0040:*/ 0x33,0x00, /* ..##..##........ */
+ /*0042:*/ 0xff,0xe0, /* ###########..... */
+ /*0044:*/ 0xff,0xe0, /* ###########..... */
+ /*0046:*/ 0x33,0x00, /* ..##..##........ */
+ /*0048:*/ 0x33,0x00, /* ..##..##........ */
+ /*004a:*/ 0x66,0x00, /* .##..##......... */
+ /*004c:*/ 0x66,0x00, /* .##..##......... */
+ /*004e:*/ 0x66,0x00, /* .##..##......... */
+/* --- new character dollar (36) starting at offset 0x0050 --- */
+ /*0050:*/ 13, 11, 21, 1, -2, /* width and bbox (w,h,x,y) */
+ /*0055:*/ 0x06,0x00, /* .....##......... */
+ /*0057:*/ 0x06,0x00, /* .....##......... */
+ /*0059:*/ 0x3f,0x80, /* ..#######....... */
+ /*005b:*/ 0x7f,0xc0, /* .#########...... */
+ /*005d:*/ 0xe6,0xe0, /* ###..##.###..... */
+ /*005f:*/ 0xc6,0x60, /* ##...##..##..... */
+ /*0061:*/ 0xc6,0x00, /* ##...##......... */
+ /*0063:*/ 0xe6,0x00, /* ###..##......... */
+ /*0065:*/ 0x76,0x00, /* .###.##......... */
+ /*0067:*/ 0x3e,0x00, /* ..#####......... */
+ /*0069:*/ 0x0f,0x80, /* ....#####....... */
+ /*006b:*/ 0x07,0xc0, /* .....#####...... */
+ /*006d:*/ 0x06,0xe0, /* .....##.###..... */
+ /*006f:*/ 0x06,0x60, /* .....##..##..... */
+ /*0071:*/ 0xc6,0x60, /* ##...##..##..... */
+ /*0073:*/ 0xc6,0x60, /* ##...##..##..... */
+ /*0075:*/ 0xe6,0xe0, /* ###..##.###..... */
+ /*0077:*/ 0x7f,0xc0, /* .#########...... */
+ /*0079:*/ 0x3f,0x80, /* ..#######....... */
+ /*007b:*/ 0x06,0x00, /* .....##......... */
+ /*007d:*/ 0x06,0x00, /* .....##......... */
+/* --- new character percent (37) starting at offset 0x007f --- */
+ /*007f:*/ 22, 19, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0084:*/ 0x00,0x06,0x00, /* .............##......... */
+ /*0087:*/ 0x3c,0x0c,0x00, /* ..####......##.......... */
+ /*008a:*/ 0x7e,0x0c,0x00, /* .######.....##.......... */
+ /*008d:*/ 0xc3,0x18,0x00, /* ##....##...##........... */
+ /*0090:*/ 0xc3,0x18,0x00, /* ##....##...##........... */
+ /*0093:*/ 0xc3,0x30,0x00, /* ##....##..##............ */
+ /*0096:*/ 0xc3,0x30,0x00, /* ##....##..##............ */
+ /*0099:*/ 0x7e,0x60,0x00, /* .######..##............. */
+ /*009c:*/ 0x3c,0x60,0x00, /* ..####...##............. */
+ /*009f:*/ 0x00,0xc0,0x00, /* ........##.............. */
+ /*00a2:*/ 0x00,0xc7,0x80, /* ........##...####....... */
+ /*00a5:*/ 0x01,0x8f,0xc0, /* .......##...######...... */
+ /*00a8:*/ 0x01,0x98,0x60, /* .......##..##....##..... */
+ /*00ab:*/ 0x03,0x18,0x60, /* ......##...##....##..... */
+ /*00ae:*/ 0x03,0x18,0x60, /* ......##...##....##..... */
+ /*00b1:*/ 0x06,0x18,0x60, /* .....##....##....##..... */
+ /*00b4:*/ 0x06,0x0f,0xc0, /* .....##.....######...... */
+ /*00b7:*/ 0x04,0x07,0x80, /* .....#.......####....... */
+/* --- new character ampersand (38) starting at offset 0x00ba --- */
+ /*00ba:*/ 17, 14, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*00bf:*/ 0x0f,0x00, /* ....####........ */
+ /*00c1:*/ 0x1f,0x80, /* ...######....... */
+ /*00c3:*/ 0x39,0xc0, /* ..###..###...... */
+ /*00c5:*/ 0x30,0xc0, /* ..##....##...... */
+ /*00c7:*/ 0x30,0xc0, /* ..##....##...... */
+ /*00c9:*/ 0x30,0xc0, /* ..##....##...... */
+ /*00cb:*/ 0x19,0x80, /* ...##..##....... */
+ /*00cd:*/ 0x0f,0x00, /* ....####........ */
+ /*00cf:*/ 0x1e,0x00, /* ...####......... */
+ /*00d1:*/ 0x3f,0x18, /* ..######...##... */
+ /*00d3:*/ 0x73,0x98, /* .###..###..##... */
+ /*00d5:*/ 0x61,0xd8, /* .##....###.##... */
+ /*00d7:*/ 0xc0,0xf0, /* ##......####.... */
+ /*00d9:*/ 0xc0,0x60, /* ##.......##..... */
+ /*00db:*/ 0xc0,0xf0, /* ##......####.... */
+ /*00dd:*/ 0xe1,0xd8, /* ###....###.##... */
+ /*00df:*/ 0x7f,0x9c, /* .########..###.. */
+ /*00e1:*/ 0x1e,0x00, /* ...####......... */
+/* --- new character quotesingle (39) starting at offset 0x00e3 --- */
+ /*00e3:*/ 6, 2, 6, 2, 13, /* width and bbox (w,h,x,y) */
+ /*00e8:*/ 0xc0, /* ##...... */
+ /*00e9:*/ 0xc0, /* ##...... */
+ /*00ea:*/ 0xc0, /* ##...... */
+ /*00eb:*/ 0xc0, /* ##...... */
+ /*00ec:*/ 0xc0, /* ##...... */
+ /*00ed:*/ 0x40, /* .#...... */
+/* --- new character parenleft (40) starting at offset 0x00ee --- */
+ /*00ee:*/ 8, 5, 24, 2, -5, /* width and bbox (w,h,x,y) */
+ /*00f3:*/ 0x18, /* ...##... */
+ /*00f4:*/ 0x18, /* ...##... */
+ /*00f5:*/ 0x30, /* ..##.... */
+ /*00f6:*/ 0x30, /* ..##.... */
+ /*00f7:*/ 0x60, /* .##..... */
+ /*00f8:*/ 0x60, /* .##..... */
+ /*00f9:*/ 0x60, /* .##..... */
+ /*00fa:*/ 0xc0, /* ##...... */
+ /*00fb:*/ 0xc0, /* ##...... */
+ /*00fc:*/ 0xc0, /* ##...... */
+ /*00fd:*/ 0xc0, /* ##...... */
+ /*00fe:*/ 0xc0, /* ##...... */
+ /*00ff:*/ 0xc0, /* ##...... */
+ /*0100:*/ 0xc0, /* ##...... */
+ /*0101:*/ 0xc0, /* ##...... */
+ /*0102:*/ 0xc0, /* ##...... */
+ /*0103:*/ 0xc0, /* ##...... */
+ /*0104:*/ 0x60, /* .##..... */
+ /*0105:*/ 0x60, /* .##..... */
+ /*0106:*/ 0x60, /* .##..... */
+ /*0107:*/ 0x30, /* ..##.... */
+ /*0108:*/ 0x30, /* ..##.... */
+ /*0109:*/ 0x18, /* ...##... */
+ /*010a:*/ 0x18, /* ...##... */
+/* --- new character parenright (41) starting at offset 0x010b --- */
+ /*010b:*/ 8, 5, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0110:*/ 0xc0, /* ##...... */
+ /*0111:*/ 0xc0, /* ##...... */
+ /*0112:*/ 0x60, /* .##..... */
+ /*0113:*/ 0x60, /* .##..... */
+ /*0114:*/ 0x30, /* ..##.... */
+ /*0115:*/ 0x30, /* ..##.... */
+ /*0116:*/ 0x30, /* ..##.... */
+ /*0117:*/ 0x18, /* ...##... */
+ /*0118:*/ 0x18, /* ...##... */
+ /*0119:*/ 0x18, /* ...##... */
+ /*011a:*/ 0x18, /* ...##... */
+ /*011b:*/ 0x18, /* ...##... */
+ /*011c:*/ 0x18, /* ...##... */
+ /*011d:*/ 0x18, /* ...##... */
+ /*011e:*/ 0x18, /* ...##... */
+ /*011f:*/ 0x18, /* ...##... */
+ /*0120:*/ 0x18, /* ...##... */
+ /*0121:*/ 0x30, /* ..##.... */
+ /*0122:*/ 0x30, /* ..##.... */
+ /*0123:*/ 0x30, /* ..##.... */
+ /*0124:*/ 0x60, /* .##..... */
+ /*0125:*/ 0x60, /* .##..... */
+ /*0126:*/ 0xc0, /* ##...... */
+ /*0127:*/ 0xc0, /* ##...... */
+/* --- new character asterisk (42) starting at offset 0x0128 --- */
+ /*0128:*/ 10, 7, 7, 1, 12, /* width and bbox (w,h,x,y) */
+ /*012d:*/ 0x10, /* ...#.... */
+ /*012e:*/ 0x10, /* ...#.... */
+ /*012f:*/ 0xd6, /* ##.#.##. */
+ /*0130:*/ 0x7c, /* .#####.. */
+ /*0131:*/ 0x38, /* ..###... */
+ /*0132:*/ 0x6c, /* .##.##.. */
+ /*0133:*/ 0x44, /* .#...#.. */
+/* --- new character plus (43) starting at offset 0x0134 --- */
+ /*0134:*/ 14, 12, 12, 1, 1, /* width and bbox (w,h,x,y) */
+ /*0139:*/ 0x06,0x00, /* .....##......... */
+ /*013b:*/ 0x06,0x00, /* .....##......... */
+ /*013d:*/ 0x06,0x00, /* .....##......... */
+ /*013f:*/ 0x06,0x00, /* .....##......... */
+ /*0141:*/ 0x06,0x00, /* .....##......... */
+ /*0143:*/ 0xff,0xf0, /* ############.... */
+ /*0145:*/ 0xff,0xf0, /* ############.... */
+ /*0147:*/ 0x06,0x00, /* .....##......... */
+ /*0149:*/ 0x06,0x00, /* .....##......... */
+ /*014b:*/ 0x06,0x00, /* .....##......... */
+ /*014d:*/ 0x06,0x00, /* .....##......... */
+ /*014f:*/ 0x06,0x00, /* .....##......... */
+/* --- new character comma (44) starting at offset 0x0151 --- */
+ /*0151:*/ 6, 2, 6, 2, -3, /* width and bbox (w,h,x,y) */
+ /*0156:*/ 0xc0, /* ##...... */
+ /*0157:*/ 0xc0, /* ##...... */
+ /*0158:*/ 0xc0, /* ##...... */
+ /*0159:*/ 0x40, /* .#...... */
+ /*015a:*/ 0x40, /* .#...... */
+ /*015b:*/ 0x80, /* #....... */
+/* --- new character hyphen (45) starting at offset 0x015c --- */
+ /*015c:*/ 8, 6, 2, 1, 6, /* width and bbox (w,h,x,y) */
+ /*0161:*/ 0xfc, /* ######.. */
+ /*0162:*/ 0xfc, /* ######.. */
+/* --- new character period (46) starting at offset 0x0163 --- */
+ /*0163:*/ 6, 2, 3, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0168:*/ 0xc0, /* ##...... */
+ /*0169:*/ 0xc0, /* ##...... */
+ /*016a:*/ 0xc0, /* ##...... */
+/* --- new character slash (47) starting at offset 0x016b --- */
+ /*016b:*/ 7, 7, 19, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0170:*/ 0x06, /* .....##. */
+ /*0171:*/ 0x06, /* .....##. */
+ /*0172:*/ 0x06, /* .....##. */
+ /*0173:*/ 0x0c, /* ....##.. */
+ /*0174:*/ 0x0c, /* ....##.. */
+ /*0175:*/ 0x0c, /* ....##.. */
+ /*0176:*/ 0x18, /* ...##... */
+ /*0177:*/ 0x18, /* ...##... */
+ /*0178:*/ 0x18, /* ...##... */
+ /*0179:*/ 0x18, /* ...##... */
+ /*017a:*/ 0x30, /* ..##.... */
+ /*017b:*/ 0x30, /* ..##.... */
+ /*017c:*/ 0x30, /* ..##.... */
+ /*017d:*/ 0x60, /* .##..... */
+ /*017e:*/ 0x60, /* .##..... */
+ /*017f:*/ 0x60, /* .##..... */
+ /*0180:*/ 0xc0, /* ##...... */
+ /*0181:*/ 0xc0, /* ##...... */
+ /*0182:*/ 0xc0, /* ##...... */
+/* --- new character zero (48) starting at offset 0x0183 --- */
+ /*0183:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0188:*/ 0x1f,0x00, /* ...#####........ */
+ /*018a:*/ 0x3f,0x80, /* ..#######....... */
+ /*018c:*/ 0x71,0xc0, /* .###...###...... */
+ /*018e:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0190:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0192:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0194:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0196:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0198:*/ 0xc0,0x60, /* ##.......##..... */
+ /*019a:*/ 0xc0,0x60, /* ##.......##..... */
+ /*019c:*/ 0xc0,0x60, /* ##.......##..... */
+ /*019e:*/ 0xc0,0x60, /* ##.......##..... */
+ /*01a0:*/ 0xc0,0x60, /* ##.......##..... */
+ /*01a2:*/ 0x60,0xc0, /* .##.....##...... */
+ /*01a4:*/ 0x60,0xc0, /* .##.....##...... */
+ /*01a6:*/ 0x71,0xc0, /* .###...###...... */
+ /*01a8:*/ 0x3f,0x80, /* ..#######....... */
+ /*01aa:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character one (49) starting at offset 0x01ac --- */
+ /*01ac:*/ 13, 6, 18, 2, 0, /* width and bbox (w,h,x,y) */
+ /*01b1:*/ 0x0c, /* ....##.. */
+ /*01b2:*/ 0x0c, /* ....##.. */
+ /*01b3:*/ 0x1c, /* ...###.. */
+ /*01b4:*/ 0xfc, /* ######.. */
+ /*01b5:*/ 0xfc, /* ######.. */
+ /*01b6:*/ 0x0c, /* ....##.. */
+ /*01b7:*/ 0x0c, /* ....##.. */
+ /*01b8:*/ 0x0c, /* ....##.. */
+ /*01b9:*/ 0x0c, /* ....##.. */
+ /*01ba:*/ 0x0c, /* ....##.. */
+ /*01bb:*/ 0x0c, /* ....##.. */
+ /*01bc:*/ 0x0c, /* ....##.. */
+ /*01bd:*/ 0x0c, /* ....##.. */
+ /*01be:*/ 0x0c, /* ....##.. */
+ /*01bf:*/ 0x0c, /* ....##.. */
+ /*01c0:*/ 0x0c, /* ....##.. */
+ /*01c1:*/ 0x0c, /* ....##.. */
+ /*01c2:*/ 0x0c, /* ....##.. */
+/* --- new character two (50) starting at offset 0x01c3 --- */
+ /*01c3:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01c8:*/ 0x1e,0x00, /* ...####......... */
+ /*01ca:*/ 0x7f,0x80, /* .########....... */
+ /*01cc:*/ 0x61,0xc0, /* .##....###...... */
+ /*01ce:*/ 0xc0,0xc0, /* ##......##...... */
+ /*01d0:*/ 0xc0,0x60, /* ##.......##..... */
+ /*01d2:*/ 0xc0,0x60, /* ##.......##..... */
+ /*01d4:*/ 0x00,0x60, /* .........##..... */
+ /*01d6:*/ 0x00,0xc0, /* ........##...... */
+ /*01d8:*/ 0x01,0xc0, /* .......###...... */
+ /*01da:*/ 0x03,0x80, /* ......###....... */
+ /*01dc:*/ 0x0f,0x00, /* ....####........ */
+ /*01de:*/ 0x1c,0x00, /* ...###.......... */
+ /*01e0:*/ 0x38,0x00, /* ..###........... */
+ /*01e2:*/ 0x70,0x00, /* .###............ */
+ /*01e4:*/ 0xe0,0x00, /* ###............. */
+ /*01e6:*/ 0xc0,0x00, /* ##.............. */
+ /*01e8:*/ 0xff,0xe0, /* ###########..... */
+ /*01ea:*/ 0xff,0xe0, /* ###########..... */
+/* --- new character three (51) starting at offset 0x01ec --- */
+ /*01ec:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*01f1:*/ 0x1f,0x00, /* ...#####........ */
+ /*01f3:*/ 0x7f,0x80, /* .########....... */
+ /*01f5:*/ 0x61,0x80, /* .##....##....... */
+ /*01f7:*/ 0xc0,0xc0, /* ##......##...... */
+ /*01f9:*/ 0xc0,0xc0, /* ##......##...... */
+ /*01fb:*/ 0xc0,0xc0, /* ##......##...... */
+ /*01fd:*/ 0x00,0xc0, /* ........##...... */
+ /*01ff:*/ 0x01,0x80, /* .......##....... */
+ /*0201:*/ 0x0f,0x00, /* ....####........ */
+ /*0203:*/ 0x0f,0xc0, /* ....######...... */
+ /*0205:*/ 0x00,0xc0, /* ........##...... */
+ /*0207:*/ 0x00,0x60, /* .........##..... */
+ /*0209:*/ 0x00,0x60, /* .........##..... */
+ /*020b:*/ 0xc0,0x60, /* ##.......##..... */
+ /*020d:*/ 0xc0,0xc0, /* ##......##...... */
+ /*020f:*/ 0x61,0xc0, /* .##....###...... */
+ /*0211:*/ 0x7f,0x80, /* .########....... */
+ /*0213:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character four (52) starting at offset 0x0215 --- */
+ /*0215:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*021a:*/ 0x01,0x80, /* .......##....... */
+ /*021c:*/ 0x03,0x80, /* ......###....... */
+ /*021e:*/ 0x03,0x80, /* ......###....... */
+ /*0220:*/ 0x07,0x80, /* .....####....... */
+ /*0222:*/ 0x0f,0x80, /* ....#####....... */
+ /*0224:*/ 0x0d,0x80, /* ....##.##....... */
+ /*0226:*/ 0x19,0x80, /* ...##..##....... */
+ /*0228:*/ 0x39,0x80, /* ..###..##....... */
+ /*022a:*/ 0x31,0x80, /* ..##...##....... */
+ /*022c:*/ 0x61,0x80, /* .##....##....... */
+ /*022e:*/ 0xe1,0x80, /* ###....##....... */
+ /*0230:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0232:*/ 0xff,0xe0, /* ###########..... */
+ /*0234:*/ 0xff,0xe0, /* ###########..... */
+ /*0236:*/ 0x01,0x80, /* .......##....... */
+ /*0238:*/ 0x01,0x80, /* .......##....... */
+ /*023a:*/ 0x01,0x80, /* .......##....... */
+ /*023c:*/ 0x01,0x80, /* .......##....... */
+/* --- new character five (53) starting at offset 0x023e --- */
+ /*023e:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0243:*/ 0x7f,0xc0, /* .#########...... */
+ /*0245:*/ 0x7f,0xc0, /* .#########...... */
+ /*0247:*/ 0x60,0x00, /* .##............. */
+ /*0249:*/ 0x60,0x00, /* .##............. */
+ /*024b:*/ 0x60,0x00, /* .##............. */
+ /*024d:*/ 0x60,0x00, /* .##............. */
+ /*024f:*/ 0x6e,0x00, /* .##.###......... */
+ /*0251:*/ 0x7f,0x80, /* .########....... */
+ /*0253:*/ 0x71,0xc0, /* .###...###...... */
+ /*0255:*/ 0x00,0xc0, /* ........##...... */
+ /*0257:*/ 0x00,0x60, /* .........##..... */
+ /*0259:*/ 0x00,0x60, /* .........##..... */
+ /*025b:*/ 0x00,0x60, /* .........##..... */
+ /*025d:*/ 0xc0,0x60, /* ##.......##..... */
+ /*025f:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0261:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0263:*/ 0x7f,0x80, /* .########....... */
+ /*0265:*/ 0x1e,0x00, /* ...####......... */
+/* --- new character six (54) starting at offset 0x0267 --- */
+ /*0267:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*026c:*/ 0x0f,0x00, /* ....####........ */
+ /*026e:*/ 0x3f,0xc0, /* ..########...... */
+ /*0270:*/ 0x70,0xc0, /* .###....##...... */
+ /*0272:*/ 0x60,0x60, /* .##......##..... */
+ /*0274:*/ 0xe0,0x60, /* ###......##..... */
+ /*0276:*/ 0xc0,0x00, /* ##.............. */
+ /*0278:*/ 0xc0,0x00, /* ##.............. */
+ /*027a:*/ 0xcf,0x00, /* ##..####........ */
+ /*027c:*/ 0xdf,0x80, /* ##.######....... */
+ /*027e:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0280:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*0282:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0284:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0286:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0288:*/ 0xe0,0x60, /* ###......##..... */
+ /*028a:*/ 0x60,0xc0, /* .##.....##...... */
+ /*028c:*/ 0x7f,0xc0, /* .#########...... */
+ /*028e:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character seven (55) starting at offset 0x0290 --- */
+ /*0290:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0295:*/ 0xff,0xe0, /* ###########..... */
+ /*0297:*/ 0xff,0xe0, /* ###########..... */
+ /*0299:*/ 0x00,0xe0, /* ........###..... */
+ /*029b:*/ 0x00,0xc0, /* ........##...... */
+ /*029d:*/ 0x01,0x80, /* .......##....... */
+ /*029f:*/ 0x01,0x80, /* .......##....... */
+ /*02a1:*/ 0x03,0x00, /* ......##........ */
+ /*02a3:*/ 0x03,0x00, /* ......##........ */
+ /*02a5:*/ 0x06,0x00, /* .....##......... */
+ /*02a7:*/ 0x06,0x00, /* .....##......... */
+ /*02a9:*/ 0x0c,0x00, /* ....##.......... */
+ /*02ab:*/ 0x0c,0x00, /* ....##.......... */
+ /*02ad:*/ 0x1c,0x00, /* ...###.......... */
+ /*02af:*/ 0x18,0x00, /* ...##........... */
+ /*02b1:*/ 0x18,0x00, /* ...##........... */
+ /*02b3:*/ 0x38,0x00, /* ..###........... */
+ /*02b5:*/ 0x30,0x00, /* ..##............ */
+ /*02b7:*/ 0x30,0x00, /* ..##............ */
+/* --- new character eight (56) starting at offset 0x02b9 --- */
+ /*02b9:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02be:*/ 0x0e,0x00, /* ....###......... */
+ /*02c0:*/ 0x3f,0x80, /* ..#######....... */
+ /*02c2:*/ 0x31,0x80, /* ..##...##....... */
+ /*02c4:*/ 0x60,0xc0, /* .##.....##...... */
+ /*02c6:*/ 0x60,0xc0, /* .##.....##...... */
+ /*02c8:*/ 0x60,0xc0, /* .##.....##...... */
+ /*02ca:*/ 0x60,0xc0, /* .##.....##...... */
+ /*02cc:*/ 0x31,0x80, /* ..##...##....... */
+ /*02ce:*/ 0x1f,0x00, /* ...#####........ */
+ /*02d0:*/ 0x3f,0x80, /* ..#######....... */
+ /*02d2:*/ 0x60,0xc0, /* .##.....##...... */
+ /*02d4:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*02d6:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02d8:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02da:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02dc:*/ 0x71,0xc0, /* .###...###...... */
+ /*02de:*/ 0x7f,0xc0, /* .#########...... */
+ /*02e0:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character nine (57) starting at offset 0x02e2 --- */
+ /*02e2:*/ 13, 11, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*02e7:*/ 0x1f,0x00, /* ...#####........ */
+ /*02e9:*/ 0x7f,0xc0, /* .#########...... */
+ /*02eb:*/ 0x71,0xc0, /* .###...###...... */
+ /*02ed:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*02ef:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02f1:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02f3:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02f5:*/ 0xc0,0x60, /* ##.......##..... */
+ /*02f7:*/ 0xe0,0xe0, /* ###.....###..... */
+ /*02f9:*/ 0x71,0xe0, /* .###...####..... */
+ /*02fb:*/ 0x7f,0x60, /* .#######.##..... */
+ /*02fd:*/ 0x1e,0x60, /* ...####..##..... */
+ /*02ff:*/ 0x00,0x60, /* .........##..... */
+ /*0301:*/ 0x00,0xe0, /* ........###..... */
+ /*0303:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0305:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0307:*/ 0x7f,0x80, /* .########....... */
+ /*0309:*/ 0x1e,0x00, /* ...####......... */
+/* --- new character colon (58) starting at offset 0x030b --- */
+ /*030b:*/ 6, 2, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0310:*/ 0xc0, /* ##...... */
+ /*0311:*/ 0xc0, /* ##...... */
+ /*0312:*/ 0xc0, /* ##...... */
+ /*0313:*/ 0x00, /* ........ */
+ /*0314:*/ 0x00, /* ........ */
+ /*0315:*/ 0x00, /* ........ */
+ /*0316:*/ 0x00, /* ........ */
+ /*0317:*/ 0x00, /* ........ */
+ /*0318:*/ 0x00, /* ........ */
+ /*0319:*/ 0x00, /* ........ */
+ /*031a:*/ 0x00, /* ........ */
+ /*031b:*/ 0xc0, /* ##...... */
+ /*031c:*/ 0xc0, /* ##...... */
+ /*031d:*/ 0xc0, /* ##...... */
+/* --- new character semicolon (59) starting at offset 0x031e --- */
+ /*031e:*/ 6, 2, 17, 2, -3, /* width and bbox (w,h,x,y) */
+ /*0323:*/ 0xc0, /* ##...... */
+ /*0324:*/ 0xc0, /* ##...... */
+ /*0325:*/ 0xc0, /* ##...... */
+ /*0326:*/ 0x00, /* ........ */
+ /*0327:*/ 0x00, /* ........ */
+ /*0328:*/ 0x00, /* ........ */
+ /*0329:*/ 0x00, /* ........ */
+ /*032a:*/ 0x00, /* ........ */
+ /*032b:*/ 0x00, /* ........ */
+ /*032c:*/ 0x00, /* ........ */
+ /*032d:*/ 0x00, /* ........ */
+ /*032e:*/ 0xc0, /* ##...... */
+ /*032f:*/ 0xc0, /* ##...... */
+ /*0330:*/ 0xc0, /* ##...... */
+ /*0331:*/ 0x40, /* .#...... */
+ /*0332:*/ 0x40, /* .#...... */
+ /*0333:*/ 0x80, /* #....... */
+/* --- new character less (60) starting at offset 0x0334 --- */
+ /*0334:*/ 15, 12, 12, 1, 1, /* width and bbox (w,h,x,y) */
+ /*0339:*/ 0x00,0x30, /* ..........##.... */
+ /*033b:*/ 0x00,0xf0, /* ........####.... */
+ /*033d:*/ 0x03,0xc0, /* ......####...... */
+ /*033f:*/ 0x0f,0x00, /* ....####........ */
+ /*0341:*/ 0x3c,0x00, /* ..####.......... */
+ /*0343:*/ 0xe0,0x00, /* ###............. */
+ /*0345:*/ 0xe0,0x00, /* ###............. */
+ /*0347:*/ 0x3c,0x00, /* ..####.......... */
+ /*0349:*/ 0x0f,0x00, /* ....####........ */
+ /*034b:*/ 0x03,0xc0, /* ......####...... */
+ /*034d:*/ 0x00,0xf0, /* ........####.... */
+ /*034f:*/ 0x00,0x30, /* ..........##.... */
+/* --- new character equal (61) starting at offset 0x0351 --- */
+ /*0351:*/ 15, 10, 6, 2, 5, /* width and bbox (w,h,x,y) */
+ /*0356:*/ 0xff,0xc0, /* ##########...... */
+ /*0358:*/ 0xff,0xc0, /* ##########...... */
+ /*035a:*/ 0x00,0x00, /* ................ */
+ /*035c:*/ 0x00,0x00, /* ................ */
+ /*035e:*/ 0xff,0xc0, /* ##########...... */
+ /*0360:*/ 0xff,0xc0, /* ##########...... */
+/* --- new character greater (62) starting at offset 0x0362 --- */
+ /*0362:*/ 15, 12, 12, 1, 1, /* width and bbox (w,h,x,y) */
+ /*0367:*/ 0xc0,0x00, /* ##.............. */
+ /*0369:*/ 0xf0,0x00, /* ####............ */
+ /*036b:*/ 0x3c,0x00, /* ..####.......... */
+ /*036d:*/ 0x0f,0x00, /* ....####........ */
+ /*036f:*/ 0x03,0xc0, /* ......####...... */
+ /*0371:*/ 0x00,0x70, /* .........###.... */
+ /*0373:*/ 0x00,0x70, /* .........###.... */
+ /*0375:*/ 0x03,0xc0, /* ......####...... */
+ /*0377:*/ 0x0f,0x00, /* ....####........ */
+ /*0379:*/ 0x3c,0x00, /* ..####.......... */
+ /*037b:*/ 0xf0,0x00, /* ####............ */
+ /*037d:*/ 0xc0,0x00, /* ##.............. */
+/* --- new character question (63) starting at offset 0x037f --- */
+ /*037f:*/ 12, 10, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0384:*/ 0x1f,0x00, /* ...#####........ */
+ /*0386:*/ 0x7f,0x80, /* .########....... */
+ /*0388:*/ 0x71,0xc0, /* .###...###...... */
+ /*038a:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*038c:*/ 0xc0,0xc0, /* ##......##...... */
+ /*038e:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*0390:*/ 0x01,0x80, /* .......##....... */
+ /*0392:*/ 0x03,0x80, /* ......###....... */
+ /*0394:*/ 0x07,0x00, /* .....###........ */
+ /*0396:*/ 0x06,0x00, /* .....##......... */
+ /*0398:*/ 0x0c,0x00, /* ....##.......... */
+ /*039a:*/ 0x0c,0x00, /* ....##.......... */
+ /*039c:*/ 0x0c,0x00, /* ....##.......... */
+ /*039e:*/ 0x0c,0x00, /* ....##.......... */
+ /*03a0:*/ 0x00,0x00, /* ................ */
+ /*03a2:*/ 0x00,0x00, /* ................ */
+ /*03a4:*/ 0x0c,0x00, /* ....##.......... */
+ /*03a6:*/ 0x0c,0x00, /* ....##.......... */
+ /*03a8:*/ 0x0c,0x00, /* ....##.......... */
+/* --- new character at (64) starting at offset 0x03aa --- */
+ /*03aa:*/ 25, 22, 23, 2, -4, /* width and bbox (w,h,x,y) */
+ /*03af:*/ 0x00,0xff,0x00, /* ........########........ */
+ /*03b2:*/ 0x03,0xff,0xc0, /* ......############...... */
+ /*03b5:*/ 0x0f,0x01,0xe0, /* ....####.......####..... */
+ /*03b8:*/ 0x1c,0x00,0x70, /* ...###...........###.... */
+ /*03bb:*/ 0x38,0x00,0x18, /* ..###..............##... */
+ /*03be:*/ 0x30,0x00,0x18, /* ..##...............##... */
+ /*03c1:*/ 0x60,0x73,0x0c, /* .##......###..##....##.. */
+ /*03c4:*/ 0x60,0xfb,0x0c, /* .##.....#####.##....##.. */
+ /*03c7:*/ 0xc1,0xc7,0x0c, /* ##.....###...###....##.. */
+ /*03ca:*/ 0xc3,0x86,0x0c, /* ##....###....##.....##.. */
+ /*03cd:*/ 0xc3,0x06,0x0c, /* ##....##.....##.....##.. */
+ /*03d0:*/ 0xc6,0x06,0x0c, /* ##...##......##.....##.. */
+ /*03d3:*/ 0xc6,0x0c,0x1c, /* ##...##.....##.....###.. */
+ /*03d6:*/ 0xc6,0x0c,0x18, /* ##...##.....##.....##... */
+ /*03d9:*/ 0xc6,0x0c,0x38, /* ##...##.....##....###... */
+ /*03dc:*/ 0xe7,0x1c,0x70, /* ###..###...###...###.... */
+ /*03df:*/ 0x63,0xf7,0xe0, /* .##...######.######..... */
+ /*03e2:*/ 0x71,0xe3,0x80, /* .###...####...###....... */
+ /*03e5:*/ 0x38,0x00,0x00, /* ..###................... */
+ /*03e8:*/ 0x1c,0x00,0x00, /* ...###.................. */
+ /*03eb:*/ 0x0f,0x03,0x00, /* ....####......##........ */
+ /*03ee:*/ 0x07,0xff,0x00, /* .....###########........ */
+ /*03f1:*/ 0x00,0xfc,0x00, /* ........######.......... */
+/* --- new character A (65) starting at offset 0x03f4 --- */
+ /*03f4:*/ 17, 15, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*03f9:*/ 0x03,0x80, /* ......###....... */
+ /*03fb:*/ 0x03,0x80, /* ......###....... */
+ /*03fd:*/ 0x06,0xc0, /* .....##.##...... */
+ /*03ff:*/ 0x06,0xc0, /* .....##.##...... */
+ /*0401:*/ 0x0c,0x40, /* ....##...#...... */
+ /*0403:*/ 0x0c,0x60, /* ....##...##..... */
+ /*0405:*/ 0x0c,0x60, /* ....##...##..... */
+ /*0407:*/ 0x18,0x30, /* ...##.....##.... */
+ /*0409:*/ 0x18,0x30, /* ...##.....##.... */
+ /*040b:*/ 0x18,0x30, /* ...##.....##.... */
+ /*040d:*/ 0x30,0x18, /* ..##.......##... */
+ /*040f:*/ 0x3f,0xf8, /* ..###########... */
+ /*0411:*/ 0x3f,0xf8, /* ..###########... */
+ /*0413:*/ 0x60,0x0c, /* .##.........##.. */
+ /*0415:*/ 0x60,0x0c, /* .##.........##.. */
+ /*0417:*/ 0x60,0x0c, /* .##.........##.. */
+ /*0419:*/ 0xc0,0x06, /* ##...........##. */
+ /*041b:*/ 0xc0,0x06, /* ##...........##. */
+ /*041d:*/ 0xc0,0x06, /* ##...........##. */
+/* --- new character B (66) starting at offset 0x041f --- */
+ /*041f:*/ 17, 14, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0424:*/ 0xff,0xc0, /* ##########...... */
+ /*0426:*/ 0xff,0xf0, /* ############.... */
+ /*0428:*/ 0xc0,0x70, /* ##.......###.... */
+ /*042a:*/ 0xc0,0x18, /* ##.........##... */
+ /*042c:*/ 0xc0,0x18, /* ##.........##... */
+ /*042e:*/ 0xc0,0x18, /* ##.........##... */
+ /*0430:*/ 0xc0,0x18, /* ##.........##... */
+ /*0432:*/ 0xc0,0x30, /* ##........##.... */
+ /*0434:*/ 0xff,0xe0, /* ###########..... */
+ /*0436:*/ 0xff,0xf0, /* ############.... */
+ /*0438:*/ 0xc0,0x18, /* ##.........##... */
+ /*043a:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*043c:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*043e:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0440:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0442:*/ 0xc0,0x1c, /* ##.........###.. */
+ /*0444:*/ 0xc0,0x38, /* ##........###... */
+ /*0446:*/ 0xff,0xf0, /* ############.... */
+ /*0448:*/ 0xff,0xc0, /* ##########...... */
+/* --- new character C (67) starting at offset 0x044a --- */
+ /*044a:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*044f:*/ 0x07,0xe0, /* .....######..... */
+ /*0451:*/ 0x1f,0xf8, /* ...##########... */
+ /*0453:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*0455:*/ 0x70,0x0e, /* .###........###. */
+ /*0457:*/ 0x60,0x06, /* .##..........##. */
+ /*0459:*/ 0xe0,0x06, /* ###..........##. */
+ /*045b:*/ 0xc0,0x00, /* ##.............. */
+ /*045d:*/ 0xc0,0x00, /* ##.............. */
+ /*045f:*/ 0xc0,0x00, /* ##.............. */
+ /*0461:*/ 0xc0,0x00, /* ##.............. */
+ /*0463:*/ 0xc0,0x00, /* ##.............. */
+ /*0465:*/ 0xc0,0x00, /* ##.............. */
+ /*0467:*/ 0xc0,0x03, /* ##............## */
+ /*0469:*/ 0xe0,0x03, /* ###...........## */
+ /*046b:*/ 0x60,0x06, /* .##..........##. */
+ /*046d:*/ 0x70,0x0e, /* .###........###. */
+ /*046f:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*0471:*/ 0x1f,0xf8, /* ...##########... */
+ /*0473:*/ 0x07,0xe0, /* .....######..... */
+/* --- new character D (68) starting at offset 0x0475 --- */
+ /*0475:*/ 18, 15, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*047a:*/ 0xff,0xc0, /* ##########...... */
+ /*047c:*/ 0xff,0xf0, /* ############.... */
+ /*047e:*/ 0xc0,0x78, /* ##.......####... */
+ /*0480:*/ 0xc0,0x1c, /* ##.........###.. */
+ /*0482:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0484:*/ 0xc0,0x0e, /* ##..........###. */
+ /*0486:*/ 0xc0,0x06, /* ##...........##. */
+ /*0488:*/ 0xc0,0x06, /* ##...........##. */
+ /*048a:*/ 0xc0,0x06, /* ##...........##. */
+ /*048c:*/ 0xc0,0x06, /* ##...........##. */
+ /*048e:*/ 0xc0,0x06, /* ##...........##. */
+ /*0490:*/ 0xc0,0x06, /* ##...........##. */
+ /*0492:*/ 0xc0,0x06, /* ##...........##. */
+ /*0494:*/ 0xc0,0x0e, /* ##..........###. */
+ /*0496:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0498:*/ 0xc0,0x1c, /* ##.........###.. */
+ /*049a:*/ 0xc0,0x78, /* ##.......####... */
+ /*049c:*/ 0xff,0xf0, /* ############.... */
+ /*049e:*/ 0xff,0xc0, /* ##########...... */
+/* --- new character E (69) starting at offset 0x04a0 --- */
+ /*04a0:*/ 16, 12, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*04a5:*/ 0xff,0xf0, /* ############.... */
+ /*04a7:*/ 0xff,0xf0, /* ############.... */
+ /*04a9:*/ 0xc0,0x00, /* ##.............. */
+ /*04ab:*/ 0xc0,0x00, /* ##.............. */
+ /*04ad:*/ 0xc0,0x00, /* ##.............. */
+ /*04af:*/ 0xc0,0x00, /* ##.............. */
+ /*04b1:*/ 0xc0,0x00, /* ##.............. */
+ /*04b3:*/ 0xc0,0x00, /* ##.............. */
+ /*04b5:*/ 0xff,0xe0, /* ###########..... */
+ /*04b7:*/ 0xff,0xe0, /* ###########..... */
+ /*04b9:*/ 0xc0,0x00, /* ##.............. */
+ /*04bb:*/ 0xc0,0x00, /* ##.............. */
+ /*04bd:*/ 0xc0,0x00, /* ##.............. */
+ /*04bf:*/ 0xc0,0x00, /* ##.............. */
+ /*04c1:*/ 0xc0,0x00, /* ##.............. */
+ /*04c3:*/ 0xc0,0x00, /* ##.............. */
+ /*04c5:*/ 0xc0,0x00, /* ##.............. */
+ /*04c7:*/ 0xff,0xf0, /* ############.... */
+ /*04c9:*/ 0xff,0xf0, /* ############.... */
+/* --- new character F (70) starting at offset 0x04cb --- */
+ /*04cb:*/ 14, 11, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*04d0:*/ 0xff,0xe0, /* ###########..... */
+ /*04d2:*/ 0xff,0xe0, /* ###########..... */
+ /*04d4:*/ 0xc0,0x00, /* ##.............. */
+ /*04d6:*/ 0xc0,0x00, /* ##.............. */
+ /*04d8:*/ 0xc0,0x00, /* ##.............. */
+ /*04da:*/ 0xc0,0x00, /* ##.............. */
+ /*04dc:*/ 0xc0,0x00, /* ##.............. */
+ /*04de:*/ 0xc0,0x00, /* ##.............. */
+ /*04e0:*/ 0xc0,0x00, /* ##.............. */
+ /*04e2:*/ 0xff,0xc0, /* ##########...... */
+ /*04e4:*/ 0xff,0xc0, /* ##########...... */
+ /*04e6:*/ 0xc0,0x00, /* ##.............. */
+ /*04e8:*/ 0xc0,0x00, /* ##.............. */
+ /*04ea:*/ 0xc0,0x00, /* ##.............. */
+ /*04ec:*/ 0xc0,0x00, /* ##.............. */
+ /*04ee:*/ 0xc0,0x00, /* ##.............. */
+ /*04f0:*/ 0xc0,0x00, /* ##.............. */
+ /*04f2:*/ 0xc0,0x00, /* ##.............. */
+ /*04f4:*/ 0xc0,0x00, /* ##.............. */
+/* --- new character G (71) starting at offset 0x04f6 --- */
+ /*04f6:*/ 19, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*04fb:*/ 0x07,0xe0, /* .....######..... */
+ /*04fd:*/ 0x1f,0xf8, /* ...##########... */
+ /*04ff:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*0501:*/ 0x70,0x0e, /* .###........###. */
+ /*0503:*/ 0x60,0x06, /* .##..........##. */
+ /*0505:*/ 0xe0,0x06, /* ###..........##. */
+ /*0507:*/ 0xc0,0x00, /* ##.............. */
+ /*0509:*/ 0xc0,0x00, /* ##.............. */
+ /*050b:*/ 0xc0,0x00, /* ##.............. */
+ /*050d:*/ 0xc0,0x7f, /* ##.......####### */
+ /*050f:*/ 0xc0,0x7f, /* ##.......####### */
+ /*0511:*/ 0xc0,0x03, /* ##............## */
+ /*0513:*/ 0xc0,0x03, /* ##............## */
+ /*0515:*/ 0xe0,0x03, /* ###...........## */
+ /*0517:*/ 0x60,0x07, /* .##..........### */
+ /*0519:*/ 0x70,0x0f, /* .###........#### */
+ /*051b:*/ 0x3c,0x3f, /* ..####....###### */
+ /*051d:*/ 0x1f,0xfb, /* ...##########.## */
+ /*051f:*/ 0x07,0xe3, /* .....######...## */
+/* --- new character H (72) starting at offset 0x0521 --- */
+ /*0521:*/ 18, 14, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0526:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0528:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*052a:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*052c:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*052e:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0530:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0532:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0534:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0536:*/ 0xff,0xfc, /* ##############.. */
+ /*0538:*/ 0xff,0xfc, /* ##############.. */
+ /*053a:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*053c:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*053e:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0540:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0542:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0544:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0546:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0548:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*054a:*/ 0xc0,0x0c, /* ##..........##.. */
+/* --- new character I (73) starting at offset 0x054c --- */
+ /*054c:*/ 8, 2, 19, 3, 0, /* width and bbox (w,h,x,y) */
+ /*0551:*/ 0xc0, /* ##...... */
+ /*0552:*/ 0xc0, /* ##...... */
+ /*0553:*/ 0xc0, /* ##...... */
+ /*0554:*/ 0xc0, /* ##...... */
+ /*0555:*/ 0xc0, /* ##...... */
+ /*0556:*/ 0xc0, /* ##...... */
+ /*0557:*/ 0xc0, /* ##...... */
+ /*0558:*/ 0xc0, /* ##...... */
+ /*0559:*/ 0xc0, /* ##...... */
+ /*055a:*/ 0xc0, /* ##...... */
+ /*055b:*/ 0xc0, /* ##...... */
+ /*055c:*/ 0xc0, /* ##...... */
+ /*055d:*/ 0xc0, /* ##...... */
+ /*055e:*/ 0xc0, /* ##...... */
+ /*055f:*/ 0xc0, /* ##...... */
+ /*0560:*/ 0xc0, /* ##...... */
+ /*0561:*/ 0xc0, /* ##...... */
+ /*0562:*/ 0xc0, /* ##...... */
+ /*0563:*/ 0xc0, /* ##...... */
+/* --- new character J (74) starting at offset 0x0564 --- */
+ /*0564:*/ 13, 10, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0569:*/ 0x00,0xc0, /* ........##...... */
+ /*056b:*/ 0x00,0xc0, /* ........##...... */
+ /*056d:*/ 0x00,0xc0, /* ........##...... */
+ /*056f:*/ 0x00,0xc0, /* ........##...... */
+ /*0571:*/ 0x00,0xc0, /* ........##...... */
+ /*0573:*/ 0x00,0xc0, /* ........##...... */
+ /*0575:*/ 0x00,0xc0, /* ........##...... */
+ /*0577:*/ 0x00,0xc0, /* ........##...... */
+ /*0579:*/ 0x00,0xc0, /* ........##...... */
+ /*057b:*/ 0x00,0xc0, /* ........##...... */
+ /*057d:*/ 0x00,0xc0, /* ........##...... */
+ /*057f:*/ 0x00,0xc0, /* ........##...... */
+ /*0581:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0583:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0585:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0587:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0589:*/ 0x61,0x80, /* .##....##....... */
+ /*058b:*/ 0x7f,0x80, /* .########....... */
+ /*058d:*/ 0x3f,0x00, /* ..######........ */
+/* --- new character K (75) starting at offset 0x058f --- */
+ /*058f:*/ 18, 15, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0594:*/ 0xc0,0x38, /* ##........###... */
+ /*0596:*/ 0xc0,0x70, /* ##.......###.... */
+ /*0598:*/ 0xc0,0xe0, /* ##......###..... */
+ /*059a:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*059c:*/ 0xc3,0x80, /* ##....###....... */
+ /*059e:*/ 0xc7,0x00, /* ##...###........ */
+ /*05a0:*/ 0xce,0x00, /* ##..###......... */
+ /*05a2:*/ 0xdc,0x00, /* ##.###.......... */
+ /*05a4:*/ 0xfc,0x00, /* ######.......... */
+ /*05a6:*/ 0xfe,0x00, /* #######......... */
+ /*05a8:*/ 0xe7,0x00, /* ###..###........ */
+ /*05aa:*/ 0xc3,0x80, /* ##....###....... */
+ /*05ac:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*05ae:*/ 0xc0,0xe0, /* ##......###..... */
+ /*05b0:*/ 0xc0,0x70, /* ##.......###.... */
+ /*05b2:*/ 0xc0,0x38, /* ##........###... */
+ /*05b4:*/ 0xc0,0x1c, /* ##.........###.. */
+ /*05b6:*/ 0xc0,0x0e, /* ##..........###. */
+ /*05b8:*/ 0xc0,0x06, /* ##...........##. */
+/* --- new character L (76) starting at offset 0x05ba --- */
+ /*05ba:*/ 14, 11, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*05bf:*/ 0xc0,0x00, /* ##.............. */
+ /*05c1:*/ 0xc0,0x00, /* ##.............. */
+ /*05c3:*/ 0xc0,0x00, /* ##.............. */
+ /*05c5:*/ 0xc0,0x00, /* ##.............. */
+ /*05c7:*/ 0xc0,0x00, /* ##.............. */
+ /*05c9:*/ 0xc0,0x00, /* ##.............. */
+ /*05cb:*/ 0xc0,0x00, /* ##.............. */
+ /*05cd:*/ 0xc0,0x00, /* ##.............. */
+ /*05cf:*/ 0xc0,0x00, /* ##.............. */
+ /*05d1:*/ 0xc0,0x00, /* ##.............. */
+ /*05d3:*/ 0xc0,0x00, /* ##.............. */
+ /*05d5:*/ 0xc0,0x00, /* ##.............. */
+ /*05d7:*/ 0xc0,0x00, /* ##.............. */
+ /*05d9:*/ 0xc0,0x00, /* ##.............. */
+ /*05db:*/ 0xc0,0x00, /* ##.............. */
+ /*05dd:*/ 0xc0,0x00, /* ##.............. */
+ /*05df:*/ 0xc0,0x00, /* ##.............. */
+ /*05e1:*/ 0xff,0xe0, /* ###########..... */
+ /*05e3:*/ 0xff,0xe0, /* ###########..... */
+/* --- new character M (77) starting at offset 0x05e5 --- */
+ /*05e5:*/ 21, 17, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*05ea:*/ 0xc0,0x01,0x80, /* ##.............##....... */
+ /*05ed:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*05f0:*/ 0xe0,0x03,0x80, /* ###...........###....... */
+ /*05f3:*/ 0xf0,0x07,0x80, /* ####.........####....... */
+ /*05f6:*/ 0xf0,0x07,0x80, /* ####.........####....... */
+ /*05f9:*/ 0xd8,0x0d,0x80, /* ##.##.......##.##....... */
+ /*05fc:*/ 0xd8,0x0d,0x80, /* ##.##.......##.##....... */
+ /*05ff:*/ 0xd8,0x0d,0x80, /* ##.##.......##.##....... */
+ /*0602:*/ 0xcc,0x19,0x80, /* ##..##.....##..##....... */
+ /*0605:*/ 0xcc,0x19,0x80, /* ##..##.....##..##....... */
+ /*0608:*/ 0xcc,0x19,0x80, /* ##..##.....##..##....... */
+ /*060b:*/ 0xc6,0x31,0x80, /* ##...##...##...##....... */
+ /*060e:*/ 0xc6,0x31,0x80, /* ##...##...##...##....... */
+ /*0611:*/ 0xc6,0x31,0x80, /* ##...##...##...##....... */
+ /*0614:*/ 0xc3,0x61,0x80, /* ##....##.##....##....... */
+ /*0617:*/ 0xc3,0x61,0x80, /* ##....##.##....##....... */
+ /*061a:*/ 0xc3,0x61,0x80, /* ##....##.##....##....... */
+ /*061d:*/ 0xc1,0xc1,0x80, /* ##.....###.....##....... */
+ /*0620:*/ 0xc1,0xc1,0x80, /* ##.....###.....##....... */
+/* --- new character N (78) starting at offset 0x0623 --- */
+ /*0623:*/ 18, 14, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0628:*/ 0xe0,0x0c, /* ###.........##.. */
+ /*062a:*/ 0xf0,0x0c, /* ####........##.. */
+ /*062c:*/ 0xf0,0x0c, /* ####........##.. */
+ /*062e:*/ 0xd8,0x0c, /* ##.##.......##.. */
+ /*0630:*/ 0xdc,0x0c, /* ##.###......##.. */
+ /*0632:*/ 0xcc,0x0c, /* ##..##......##.. */
+ /*0634:*/ 0xce,0x0c, /* ##..###.....##.. */
+ /*0636:*/ 0xc6,0x0c, /* ##...##.....##.. */
+ /*0638:*/ 0xc7,0x0c, /* ##...###....##.. */
+ /*063a:*/ 0xc3,0x0c, /* ##....##....##.. */
+ /*063c:*/ 0xc3,0x8c, /* ##....###...##.. */
+ /*063e:*/ 0xc1,0x8c, /* ##.....##...##.. */
+ /*0640:*/ 0xc1,0xcc, /* ##.....###..##.. */
+ /*0642:*/ 0xc0,0xcc, /* ##......##..##.. */
+ /*0644:*/ 0xc0,0xec, /* ##......###.##.. */
+ /*0646:*/ 0xc0,0x6c, /* ##.......##.##.. */
+ /*0648:*/ 0xc0,0x3c, /* ##........####.. */
+ /*064a:*/ 0xc0,0x3c, /* ##........####.. */
+ /*064c:*/ 0xc0,0x1c, /* ##.........###.. */
+/* --- new character O (79) starting at offset 0x064e --- */
+ /*064e:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0653:*/ 0x07,0xe0, /* .....######..... */
+ /*0655:*/ 0x1f,0xf8, /* ...##########... */
+ /*0657:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*0659:*/ 0x70,0x0e, /* .###........###. */
+ /*065b:*/ 0x60,0x06, /* .##..........##. */
+ /*065d:*/ 0xe0,0x07, /* ###..........### */
+ /*065f:*/ 0xc0,0x03, /* ##............## */
+ /*0661:*/ 0xc0,0x03, /* ##............## */
+ /*0663:*/ 0xc0,0x03, /* ##............## */
+ /*0665:*/ 0xc0,0x03, /* ##............## */
+ /*0667:*/ 0xc0,0x03, /* ##............## */
+ /*0669:*/ 0xc0,0x03, /* ##............## */
+ /*066b:*/ 0xc0,0x03, /* ##............## */
+ /*066d:*/ 0xe0,0x07, /* ###..........### */
+ /*066f:*/ 0x60,0x06, /* .##..........##. */
+ /*0671:*/ 0x70,0x0e, /* .###........###. */
+ /*0673:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*0675:*/ 0x1f,0xf8, /* ...##########... */
+ /*0677:*/ 0x07,0xe0, /* .....######..... */
+/* --- new character P (80) starting at offset 0x0679 --- */
+ /*0679:*/ 16, 13, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*067e:*/ 0xff,0xe0, /* ###########..... */
+ /*0680:*/ 0xff,0xf0, /* ############.... */
+ /*0682:*/ 0xc0,0x30, /* ##........##.... */
+ /*0684:*/ 0xc0,0x18, /* ##.........##... */
+ /*0686:*/ 0xc0,0x18, /* ##.........##... */
+ /*0688:*/ 0xc0,0x18, /* ##.........##... */
+ /*068a:*/ 0xc0,0x18, /* ##.........##... */
+ /*068c:*/ 0xc0,0x30, /* ##........##.... */
+ /*068e:*/ 0xff,0xf0, /* ############.... */
+ /*0690:*/ 0xff,0xe0, /* ###########..... */
+ /*0692:*/ 0xc0,0x00, /* ##.............. */
+ /*0694:*/ 0xc0,0x00, /* ##.............. */
+ /*0696:*/ 0xc0,0x00, /* ##.............. */
+ /*0698:*/ 0xc0,0x00, /* ##.............. */
+ /*069a:*/ 0xc0,0x00, /* ##.............. */
+ /*069c:*/ 0xc0,0x00, /* ##.............. */
+ /*069e:*/ 0xc0,0x00, /* ##.............. */
+ /*06a0:*/ 0xc0,0x00, /* ##.............. */
+ /*06a2:*/ 0xc0,0x00, /* ##.............. */
+/* --- new character Q (81) starting at offset 0x06a4 --- */
+ /*06a4:*/ 18, 16, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*06a9:*/ 0x07,0xe0, /* .....######..... */
+ /*06ab:*/ 0x1f,0xf8, /* ...##########... */
+ /*06ad:*/ 0x3c,0x3c, /* ..####....####.. */
+ /*06af:*/ 0x70,0x0e, /* .###........###. */
+ /*06b1:*/ 0x60,0x06, /* .##..........##. */
+ /*06b3:*/ 0xe0,0x07, /* ###..........### */
+ /*06b5:*/ 0xc0,0x03, /* ##............## */
+ /*06b7:*/ 0xc0,0x03, /* ##............## */
+ /*06b9:*/ 0xc0,0x03, /* ##............## */
+ /*06bb:*/ 0xc0,0x03, /* ##............## */
+ /*06bd:*/ 0xc0,0x03, /* ##............## */
+ /*06bf:*/ 0xc0,0x03, /* ##............## */
+ /*06c1:*/ 0xc0,0x03, /* ##............## */
+ /*06c3:*/ 0xe0,0x07, /* ###..........### */
+ /*06c5:*/ 0x60,0xe6, /* .##.....###..##. */
+ /*06c7:*/ 0x70,0x7e, /* .###.....######. */
+ /*06c9:*/ 0x3c,0x1c, /* ..####.....###.. */
+ /*06cb:*/ 0x1f,0xfe, /* ...############. */
+ /*06cd:*/ 0x07,0xe7, /* .....######..### */
+/* --- new character R (82) starting at offset 0x06cf --- */
+ /*06cf:*/ 17, 13, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*06d4:*/ 0xff,0xe0, /* ###########..... */
+ /*06d6:*/ 0xff,0xf0, /* ############.... */
+ /*06d8:*/ 0xc0,0x30, /* ##........##.... */
+ /*06da:*/ 0xc0,0x18, /* ##.........##... */
+ /*06dc:*/ 0xc0,0x18, /* ##.........##... */
+ /*06de:*/ 0xc0,0x18, /* ##.........##... */
+ /*06e0:*/ 0xc0,0x18, /* ##.........##... */
+ /*06e2:*/ 0xc0,0x30, /* ##........##.... */
+ /*06e4:*/ 0xff,0xf0, /* ############.... */
+ /*06e6:*/ 0xff,0xe0, /* ###########..... */
+ /*06e8:*/ 0xc0,0x70, /* ##.......###.... */
+ /*06ea:*/ 0xc0,0x30, /* ##........##.... */
+ /*06ec:*/ 0xc0,0x18, /* ##.........##... */
+ /*06ee:*/ 0xc0,0x18, /* ##.........##... */
+ /*06f0:*/ 0xc0,0x18, /* ##.........##... */
+ /*06f2:*/ 0xc0,0x18, /* ##.........##... */
+ /*06f4:*/ 0xc0,0x18, /* ##.........##... */
+ /*06f6:*/ 0xc0,0x18, /* ##.........##... */
+ /*06f8:*/ 0xc0,0x18, /* ##.........##... */
+/* --- new character S (83) starting at offset 0x06fa --- */
+ /*06fa:*/ 16, 14, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*06ff:*/ 0x07,0xc0, /* .....#####...... */
+ /*0701:*/ 0x1f,0xf0, /* ...#########.... */
+ /*0703:*/ 0x38,0x38, /* ..###.....###... */
+ /*0705:*/ 0x70,0x18, /* .###.......##... */
+ /*0707:*/ 0x60,0x18, /* .##........##... */
+ /*0709:*/ 0x60,0x00, /* .##............. */
+ /*070b:*/ 0x70,0x00, /* .###............ */
+ /*070d:*/ 0x3e,0x00, /* ..#####......... */
+ /*070f:*/ 0x0f,0xc0, /* ....######...... */
+ /*0711:*/ 0x01,0xf0, /* .......#####.... */
+ /*0713:*/ 0x00,0x78, /* .........####... */
+ /*0715:*/ 0x00,0x1c, /* ...........###.. */
+ /*0717:*/ 0x00,0x0c, /* ............##.. */
+ /*0719:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*071b:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*071d:*/ 0xe0,0x1c, /* ###........###.. */
+ /*071f:*/ 0x78,0x38, /* .####.....###... */
+ /*0721:*/ 0x3f,0xf0, /* ..##########.... */
+ /*0723:*/ 0x0f,0xc0, /* ....######...... */
+/* --- new character T (84) starting at offset 0x0725 --- */
+ /*0725:*/ 16, 14, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*072a:*/ 0xff,0xfc, /* ##############.. */
+ /*072c:*/ 0xff,0xfc, /* ##############.. */
+ /*072e:*/ 0x03,0x00, /* ......##........ */
+ /*0730:*/ 0x03,0x00, /* ......##........ */
+ /*0732:*/ 0x03,0x00, /* ......##........ */
+ /*0734:*/ 0x03,0x00, /* ......##........ */
+ /*0736:*/ 0x03,0x00, /* ......##........ */
+ /*0738:*/ 0x03,0x00, /* ......##........ */
+ /*073a:*/ 0x03,0x00, /* ......##........ */
+ /*073c:*/ 0x03,0x00, /* ......##........ */
+ /*073e:*/ 0x03,0x00, /* ......##........ */
+ /*0740:*/ 0x03,0x00, /* ......##........ */
+ /*0742:*/ 0x03,0x00, /* ......##........ */
+ /*0744:*/ 0x03,0x00, /* ......##........ */
+ /*0746:*/ 0x03,0x00, /* ......##........ */
+ /*0748:*/ 0x03,0x00, /* ......##........ */
+ /*074a:*/ 0x03,0x00, /* ......##........ */
+ /*074c:*/ 0x03,0x00, /* ......##........ */
+ /*074e:*/ 0x03,0x00, /* ......##........ */
+/* --- new character U (85) starting at offset 0x0750 --- */
+ /*0750:*/ 18, 14, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0755:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0757:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0759:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*075b:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*075d:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*075f:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0761:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0763:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0765:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0767:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0769:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*076b:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*076d:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*076f:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0771:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0773:*/ 0x60,0x18, /* .##........##... */
+ /*0775:*/ 0x70,0x38, /* .###......###... */
+ /*0777:*/ 0x3f,0xf0, /* ..##########.... */
+ /*0779:*/ 0x0f,0xc0, /* ....######...... */
+/* --- new character V (86) starting at offset 0x077b --- */
+ /*077b:*/ 17, 15, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0780:*/ 0xc0,0x06, /* ##...........##. */
+ /*0782:*/ 0xc0,0x06, /* ##...........##. */
+ /*0784:*/ 0xe0,0x0e, /* ###.........###. */
+ /*0786:*/ 0x60,0x0c, /* .##.........##.. */
+ /*0788:*/ 0x70,0x1c, /* .###.......###.. */
+ /*078a:*/ 0x30,0x18, /* ..##.......##... */
+ /*078c:*/ 0x30,0x18, /* ..##.......##... */
+ /*078e:*/ 0x38,0x38, /* ..###.....###... */
+ /*0790:*/ 0x18,0x30, /* ...##.....##.... */
+ /*0792:*/ 0x18,0x30, /* ...##.....##.... */
+ /*0794:*/ 0x1c,0x70, /* ...###...###.... */
+ /*0796:*/ 0x0c,0x60, /* ....##...##..... */
+ /*0798:*/ 0x0c,0x60, /* ....##...##..... */
+ /*079a:*/ 0x0e,0xe0, /* ....###.###..... */
+ /*079c:*/ 0x06,0xc0, /* .....##.##...... */
+ /*079e:*/ 0x06,0xc0, /* .....##.##...... */
+ /*07a0:*/ 0x03,0x80, /* ......###....... */
+ /*07a2:*/ 0x03,0x80, /* ......###....... */
+ /*07a4:*/ 0x03,0x80, /* ......###....... */
+/* --- new character W (87) starting at offset 0x07a6 --- */
+ /*07a6:*/ 22, 20, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*07ab:*/ 0xc0,0x60,0x30, /* ##.......##.......##.... */
+ /*07ae:*/ 0xc0,0x60,0x30, /* ##.......##.......##.... */
+ /*07b1:*/ 0xc0,0x60,0x30, /* ##.......##.......##.... */
+ /*07b4:*/ 0xc0,0xf0,0x30, /* ##......####......##.... */
+ /*07b7:*/ 0x60,0xf0,0x60, /* .##.....####.....##..... */
+ /*07ba:*/ 0x61,0x98,0x60, /* .##....##..##....##..... */
+ /*07bd:*/ 0x61,0x98,0x60, /* .##....##..##....##..... */
+ /*07c0:*/ 0x61,0x98,0x60, /* .##....##..##....##..... */
+ /*07c3:*/ 0x61,0x98,0x60, /* .##....##..##....##..... */
+ /*07c6:*/ 0x31,0x98,0xc0, /* ..##...##..##...##...... */
+ /*07c9:*/ 0x33,0x0c,0xc0, /* ..##..##....##..##...... */
+ /*07cc:*/ 0x33,0x0c,0xc0, /* ..##..##....##..##...... */
+ /*07cf:*/ 0x33,0x0c,0xc0, /* ..##..##....##..##...... */
+ /*07d2:*/ 0x1b,0x0d,0x80, /* ...##.##....##.##....... */
+ /*07d5:*/ 0x1b,0x0d,0x80, /* ...##.##....##.##....... */
+ /*07d8:*/ 0x1e,0x07,0x80, /* ...####......####....... */
+ /*07db:*/ 0x0e,0x07,0x00, /* ....###......###........ */
+ /*07de:*/ 0x0c,0x03,0x00, /* ....##........##........ */
+ /*07e1:*/ 0x0c,0x03,0x00, /* ....##........##........ */
+/* --- new character X (88) starting at offset 0x07e4 --- */
+ /*07e4:*/ 17, 15, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*07e9:*/ 0xc0,0x06, /* ##...........##. */
+ /*07eb:*/ 0xe0,0x0e, /* ###.........###. */
+ /*07ed:*/ 0x70,0x1c, /* .###.......###.. */
+ /*07ef:*/ 0x30,0x18, /* ..##.......##... */
+ /*07f1:*/ 0x18,0x30, /* ...##.....##.... */
+ /*07f3:*/ 0x1c,0x70, /* ...###...###.... */
+ /*07f5:*/ 0x0e,0xe0, /* ....###.###..... */
+ /*07f7:*/ 0x07,0xc0, /* .....#####...... */
+ /*07f9:*/ 0x03,0x80, /* ......###....... */
+ /*07fb:*/ 0x03,0x80, /* ......###....... */
+ /*07fd:*/ 0x07,0xc0, /* .....#####...... */
+ /*07ff:*/ 0x0e,0xe0, /* ....###.###..... */
+ /*0801:*/ 0x0c,0x60, /* ....##...##..... */
+ /*0803:*/ 0x1c,0x70, /* ...###...###.... */
+ /*0805:*/ 0x38,0x38, /* ..###.....###... */
+ /*0807:*/ 0x30,0x18, /* ..##.......##... */
+ /*0809:*/ 0x60,0x0c, /* .##.........##.. */
+ /*080b:*/ 0xe0,0x0e, /* ###.........###. */
+ /*080d:*/ 0xc0,0x06, /* ##...........##. */
+/* --- new character Y (89) starting at offset 0x080f --- */
+ /*080f:*/ 16, 14, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0814:*/ 0xc0,0x0c, /* ##..........##.. */
+ /*0816:*/ 0xe0,0x1c, /* ###........###.. */
+ /*0818:*/ 0x60,0x18, /* .##........##... */
+ /*081a:*/ 0x70,0x38, /* .###......###... */
+ /*081c:*/ 0x30,0x30, /* ..##......##.... */
+ /*081e:*/ 0x38,0x70, /* ..###....###.... */
+ /*0820:*/ 0x18,0x60, /* ...##....##..... */
+ /*0822:*/ 0x1c,0xe0, /* ...###..###..... */
+ /*0824:*/ 0x0c,0xc0, /* ....##..##...... */
+ /*0826:*/ 0x0f,0xc0, /* ....######...... */
+ /*0828:*/ 0x07,0x80, /* .....####....... */
+ /*082a:*/ 0x07,0x80, /* .....####....... */
+ /*082c:*/ 0x03,0x00, /* ......##........ */
+ /*082e:*/ 0x03,0x00, /* ......##........ */
+ /*0830:*/ 0x03,0x00, /* ......##........ */
+ /*0832:*/ 0x03,0x00, /* ......##........ */
+ /*0834:*/ 0x03,0x00, /* ......##........ */
+ /*0836:*/ 0x03,0x00, /* ......##........ */
+ /*0838:*/ 0x03,0x00, /* ......##........ */
+/* --- new character Z (90) starting at offset 0x083a --- */
+ /*083a:*/ 15, 13, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*083f:*/ 0xff,0xf8, /* #############... */
+ /*0841:*/ 0xff,0xf8, /* #############... */
+ /*0843:*/ 0x00,0x38, /* ..........###... */
+ /*0845:*/ 0x00,0x70, /* .........###.... */
+ /*0847:*/ 0x00,0xe0, /* ........###..... */
+ /*0849:*/ 0x01,0xc0, /* .......###...... */
+ /*084b:*/ 0x01,0xc0, /* .......###...... */
+ /*084d:*/ 0x03,0x80, /* ......###....... */
+ /*084f:*/ 0x07,0x00, /* .....###........ */
+ /*0851:*/ 0x07,0x00, /* .....###........ */
+ /*0853:*/ 0x0e,0x00, /* ....###......... */
+ /*0855:*/ 0x1c,0x00, /* ...###.......... */
+ /*0857:*/ 0x1c,0x00, /* ...###.......... */
+ /*0859:*/ 0x38,0x00, /* ..###........... */
+ /*085b:*/ 0x70,0x00, /* .###............ */
+ /*085d:*/ 0x70,0x00, /* .###............ */
+ /*085f:*/ 0xe0,0x00, /* ###............. */
+ /*0861:*/ 0xff,0xf8, /* #############... */
+ /*0863:*/ 0xff,0xf8, /* #############... */
+/* --- new character bracketleft (91) starting at offset 0x0865 --- */
+ /*0865:*/ 7, 4, 24, 2, -5, /* width and bbox (w,h,x,y) */
+ /*086a:*/ 0xf0, /* ####.... */
+ /*086b:*/ 0xf0, /* ####.... */
+ /*086c:*/ 0xc0, /* ##...... */
+ /*086d:*/ 0xc0, /* ##...... */
+ /*086e:*/ 0xc0, /* ##...... */
+ /*086f:*/ 0xc0, /* ##...... */
+ /*0870:*/ 0xc0, /* ##...... */
+ /*0871:*/ 0xc0, /* ##...... */
+ /*0872:*/ 0xc0, /* ##...... */
+ /*0873:*/ 0xc0, /* ##...... */
+ /*0874:*/ 0xc0, /* ##...... */
+ /*0875:*/ 0xc0, /* ##...... */
+ /*0876:*/ 0xc0, /* ##...... */
+ /*0877:*/ 0xc0, /* ##...... */
+ /*0878:*/ 0xc0, /* ##...... */
+ /*0879:*/ 0xc0, /* ##...... */
+ /*087a:*/ 0xc0, /* ##...... */
+ /*087b:*/ 0xc0, /* ##...... */
+ /*087c:*/ 0xc0, /* ##...... */
+ /*087d:*/ 0xc0, /* ##...... */
+ /*087e:*/ 0xc0, /* ##...... */
+ /*087f:*/ 0xc0, /* ##...... */
+ /*0880:*/ 0xf0, /* ####.... */
+ /*0881:*/ 0xf0, /* ####.... */
+/* --- new character backslash (92) starting at offset 0x0882 --- */
+ /*0882:*/ 7, 7, 19, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0887:*/ 0xc0, /* ##...... */
+ /*0888:*/ 0xc0, /* ##...... */
+ /*0889:*/ 0xc0, /* ##...... */
+ /*088a:*/ 0x60, /* .##..... */
+ /*088b:*/ 0x60, /* .##..... */
+ /*088c:*/ 0x60, /* .##..... */
+ /*088d:*/ 0x30, /* ..##.... */
+ /*088e:*/ 0x30, /* ..##.... */
+ /*088f:*/ 0x30, /* ..##.... */
+ /*0890:*/ 0x30, /* ..##.... */
+ /*0891:*/ 0x18, /* ...##... */
+ /*0892:*/ 0x18, /* ...##... */
+ /*0893:*/ 0x18, /* ...##... */
+ /*0894:*/ 0x0c, /* ....##.. */
+ /*0895:*/ 0x0c, /* ....##.. */
+ /*0896:*/ 0x0c, /* ....##.. */
+ /*0897:*/ 0x06, /* .....##. */
+ /*0898:*/ 0x06, /* .....##. */
+ /*0899:*/ 0x06, /* .....##. */
+/* --- new character bracketright (93) starting at offset 0x089a --- */
+ /*089a:*/ 7, 4, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*089f:*/ 0xf0, /* ####.... */
+ /*08a0:*/ 0xf0, /* ####.... */
+ /*08a1:*/ 0x30, /* ..##.... */
+ /*08a2:*/ 0x30, /* ..##.... */
+ /*08a3:*/ 0x30, /* ..##.... */
+ /*08a4:*/ 0x30, /* ..##.... */
+ /*08a5:*/ 0x30, /* ..##.... */
+ /*08a6:*/ 0x30, /* ..##.... */
+ /*08a7:*/ 0x30, /* ..##.... */
+ /*08a8:*/ 0x30, /* ..##.... */
+ /*08a9:*/ 0x30, /* ..##.... */
+ /*08aa:*/ 0x30, /* ..##.... */
+ /*08ab:*/ 0x30, /* ..##.... */
+ /*08ac:*/ 0x30, /* ..##.... */
+ /*08ad:*/ 0x30, /* ..##.... */
+ /*08ae:*/ 0x30, /* ..##.... */
+ /*08af:*/ 0x30, /* ..##.... */
+ /*08b0:*/ 0x30, /* ..##.... */
+ /*08b1:*/ 0x30, /* ..##.... */
+ /*08b2:*/ 0x30, /* ..##.... */
+ /*08b3:*/ 0x30, /* ..##.... */
+ /*08b4:*/ 0x30, /* ..##.... */
+ /*08b5:*/ 0xf0, /* ####.... */
+ /*08b6:*/ 0xf0, /* ####.... */
+/* --- new character asciicircum (94) starting at offset 0x08b7 --- */
+ /*08b7:*/ 12, 10, 9, 1, 10, /* width and bbox (w,h,x,y) */
+ /*08bc:*/ 0x0c,0x00, /* ....##.......... */
+ /*08be:*/ 0x0c,0x00, /* ....##.......... */
+ /*08c0:*/ 0x1e,0x00, /* ...####......... */
+ /*08c2:*/ 0x12,0x00, /* ...#..#......... */
+ /*08c4:*/ 0x33,0x00, /* ..##..##........ */
+ /*08c6:*/ 0x61,0x80, /* .##....##....... */
+ /*08c8:*/ 0x61,0x80, /* .##....##....... */
+ /*08ca:*/ 0xc0,0xc0, /* ##......##...... */
+ /*08cc:*/ 0xc0,0xc0, /* ##......##...... */
+/* --- new character underscore (95) starting at offset 0x08ce --- */
+ /*08ce:*/ 14, 14, 2, 0, -5, /* width and bbox (w,h,x,y) */
+ /*08d3:*/ 0xff,0xfc, /* ##############.. */
+ /*08d5:*/ 0xff,0xfc, /* ##############.. */
+/* --- new character grave (96) starting at offset 0x08d7 --- */
+ /*08d7:*/ 7, 5, 4, 1, 15, /* width and bbox (w,h,x,y) */
+ /*08dc:*/ 0xc0, /* ##...... */
+ /*08dd:*/ 0x60, /* .##..... */
+ /*08de:*/ 0x30, /* ..##.... */
+ /*08df:*/ 0x18, /* ...##... */
+/* --- new character a (97) starting at offset 0x08e0 --- */
+ /*08e0:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*08e5:*/ 0x1f,0x00, /* ...#####........ */
+ /*08e7:*/ 0x3f,0x80, /* ..#######....... */
+ /*08e9:*/ 0x61,0xc0, /* .##....###...... */
+ /*08eb:*/ 0x60,0xc0, /* .##.....##...... */
+ /*08ed:*/ 0x00,0xc0, /* ........##...... */
+ /*08ef:*/ 0x07,0xc0, /* .....#####...... */
+ /*08f1:*/ 0x3f,0xc0, /* ..########...... */
+ /*08f3:*/ 0x78,0xc0, /* .####...##...... */
+ /*08f5:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*08f7:*/ 0xc0,0xc0, /* ##......##...... */
+ /*08f9:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*08fb:*/ 0xe3,0xc0, /* ###...####...... */
+ /*08fd:*/ 0x7e,0xe0, /* .######.###..... */
+ /*08ff:*/ 0x3c,0x60, /* ..####...##..... */
+/* --- new character b (98) starting at offset 0x0901 --- */
+ /*0901:*/ 14, 11, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0906:*/ 0xc0,0x00, /* ##.............. */
+ /*0908:*/ 0xc0,0x00, /* ##.............. */
+ /*090a:*/ 0xc0,0x00, /* ##.............. */
+ /*090c:*/ 0xc0,0x00, /* ##.............. */
+ /*090e:*/ 0xc0,0x00, /* ##.............. */
+ /*0910:*/ 0xcf,0x00, /* ##..####........ */
+ /*0912:*/ 0xdf,0x80, /* ##.######....... */
+ /*0914:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0916:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*0918:*/ 0xc0,0x60, /* ##.......##..... */
+ /*091a:*/ 0xc0,0x60, /* ##.......##..... */
+ /*091c:*/ 0xc0,0x60, /* ##.......##..... */
+ /*091e:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0920:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0922:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0924:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*0926:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0928:*/ 0xdf,0x80, /* ##.######....... */
+ /*092a:*/ 0xcf,0x00, /* ##..####........ */
+/* --- new character c (99) starting at offset 0x092c --- */
+ /*092c:*/ 12, 10, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0931:*/ 0x1f,0x00, /* ...#####........ */
+ /*0933:*/ 0x3f,0x80, /* ..#######....... */
+ /*0935:*/ 0x71,0xc0, /* .###...###...... */
+ /*0937:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0939:*/ 0xc0,0x00, /* ##.............. */
+ /*093b:*/ 0xc0,0x00, /* ##.............. */
+ /*093d:*/ 0xc0,0x00, /* ##.............. */
+ /*093f:*/ 0xc0,0x00, /* ##.............. */
+ /*0941:*/ 0xc0,0x00, /* ##.............. */
+ /*0943:*/ 0xc0,0x00, /* ##.............. */
+ /*0945:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0947:*/ 0x71,0xc0, /* .###...###...... */
+ /*0949:*/ 0x3f,0x80, /* ..#######....... */
+ /*094b:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character d (100) starting at offset 0x094d --- */
+ /*094d:*/ 14, 11, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0952:*/ 0x00,0x60, /* .........##..... */
+ /*0954:*/ 0x00,0x60, /* .........##..... */
+ /*0956:*/ 0x00,0x60, /* .........##..... */
+ /*0958:*/ 0x00,0x60, /* .........##..... */
+ /*095a:*/ 0x00,0x60, /* .........##..... */
+ /*095c:*/ 0x1e,0x60, /* ...####..##..... */
+ /*095e:*/ 0x3f,0x60, /* ..######.##..... */
+ /*0960:*/ 0x71,0xe0, /* .###...####..... */
+ /*0962:*/ 0x60,0xe0, /* .##.....###..... */
+ /*0964:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0966:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0968:*/ 0xc0,0x60, /* ##.......##..... */
+ /*096a:*/ 0xc0,0x60, /* ##.......##..... */
+ /*096c:*/ 0xc0,0x60, /* ##.......##..... */
+ /*096e:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0970:*/ 0x60,0xe0, /* .##.....###..... */
+ /*0972:*/ 0x71,0xe0, /* .###...####..... */
+ /*0974:*/ 0x3f,0x60, /* ..######.##..... */
+ /*0976:*/ 0x1e,0x60, /* ...####..##..... */
+/* --- new character e (101) starting at offset 0x0978 --- */
+ /*0978:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*097d:*/ 0x0e,0x00, /* ....###......... */
+ /*097f:*/ 0x3f,0x80, /* ..#######....... */
+ /*0981:*/ 0x71,0xc0, /* .###...###...... */
+ /*0983:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0985:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0987:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0989:*/ 0xff,0xe0, /* ###########..... */
+ /*098b:*/ 0xff,0xe0, /* ###########..... */
+ /*098d:*/ 0xc0,0x00, /* ##.............. */
+ /*098f:*/ 0xc0,0x00, /* ##.............. */
+ /*0991:*/ 0x60,0x60, /* .##......##..... */
+ /*0993:*/ 0x70,0xe0, /* .###....###..... */
+ /*0995:*/ 0x3f,0xc0, /* ..########...... */
+ /*0997:*/ 0x0f,0x00, /* ....####........ */
+/* --- new character f (102) starting at offset 0x0999 --- */
+ /*0999:*/ 8, 6, 19, 1, 0, /* width and bbox (w,h,x,y) */
+ /*099e:*/ 0x1c, /* ...###.. */
+ /*099f:*/ 0x3c, /* ..####.. */
+ /*09a0:*/ 0x30, /* ..##.... */
+ /*09a1:*/ 0x30, /* ..##.... */
+ /*09a2:*/ 0x30, /* ..##.... */
+ /*09a3:*/ 0xfc, /* ######.. */
+ /*09a4:*/ 0xfc, /* ######.. */
+ /*09a5:*/ 0x30, /* ..##.... */
+ /*09a6:*/ 0x30, /* ..##.... */
+ /*09a7:*/ 0x30, /* ..##.... */
+ /*09a8:*/ 0x30, /* ..##.... */
+ /*09a9:*/ 0x30, /* ..##.... */
+ /*09aa:*/ 0x30, /* ..##.... */
+ /*09ab:*/ 0x30, /* ..##.... */
+ /*09ac:*/ 0x30, /* ..##.... */
+ /*09ad:*/ 0x30, /* ..##.... */
+ /*09ae:*/ 0x30, /* ..##.... */
+ /*09af:*/ 0x30, /* ..##.... */
+ /*09b0:*/ 0x30, /* ..##.... */
+/* --- new character g (103) starting at offset 0x09b1 --- */
+ /*09b1:*/ 14, 11, 19, 1, -5, /* width and bbox (w,h,x,y) */
+ /*09b6:*/ 0x1e,0x60, /* ...####..##..... */
+ /*09b8:*/ 0x3f,0x60, /* ..######.##..... */
+ /*09ba:*/ 0x71,0xe0, /* .###...####..... */
+ /*09bc:*/ 0x60,0xe0, /* .##.....###..... */
+ /*09be:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09c0:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09c2:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09c4:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09c6:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09c8:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09ca:*/ 0x60,0xe0, /* .##.....###..... */
+ /*09cc:*/ 0x71,0xe0, /* .###...####..... */
+ /*09ce:*/ 0x3f,0x60, /* ..######.##..... */
+ /*09d0:*/ 0x1e,0x60, /* ...####..##..... */
+ /*09d2:*/ 0x00,0x60, /* .........##..... */
+ /*09d4:*/ 0xc0,0x60, /* ##.......##..... */
+ /*09d6:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*09d8:*/ 0x7f,0xc0, /* .#########...... */
+ /*09da:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character h (104) starting at offset 0x09dc --- */
+ /*09dc:*/ 13, 10, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*09e1:*/ 0xc0,0x00, /* ##.............. */
+ /*09e3:*/ 0xc0,0x00, /* ##.............. */
+ /*09e5:*/ 0xc0,0x00, /* ##.............. */
+ /*09e7:*/ 0xc0,0x00, /* ##.............. */
+ /*09e9:*/ 0xc0,0x00, /* ##.............. */
+ /*09eb:*/ 0xce,0x00, /* ##..###......... */
+ /*09ed:*/ 0xdf,0x80, /* ##.######....... */
+ /*09ef:*/ 0xf1,0x80, /* ####...##....... */
+ /*09f1:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*09f3:*/ 0xc0,0xc0, /* ##......##...... */
+ /*09f5:*/ 0xc0,0xc0, /* ##......##...... */
+ /*09f7:*/ 0xc0,0xc0, /* ##......##...... */
+ /*09f9:*/ 0xc0,0xc0, /* ##......##...... */
+ /*09fb:*/ 0xc0,0xc0, /* ##......##...... */
+ /*09fd:*/ 0xc0,0xc0, /* ##......##...... */
+ /*09ff:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0a01:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0a03:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0a05:*/ 0xc0,0xc0, /* ##......##...... */
+/* --- new character i (105) starting at offset 0x0a07 --- */
+ /*0a07:*/ 6, 2, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a0c:*/ 0xc0, /* ##...... */
+ /*0a0d:*/ 0xc0, /* ##...... */
+ /*0a0e:*/ 0xc0, /* ##...... */
+ /*0a0f:*/ 0x00, /* ........ */
+ /*0a10:*/ 0x00, /* ........ */
+ /*0a11:*/ 0xc0, /* ##...... */
+ /*0a12:*/ 0xc0, /* ##...... */
+ /*0a13:*/ 0xc0, /* ##...... */
+ /*0a14:*/ 0xc0, /* ##...... */
+ /*0a15:*/ 0xc0, /* ##...... */
+ /*0a16:*/ 0xc0, /* ##...... */
+ /*0a17:*/ 0xc0, /* ##...... */
+ /*0a18:*/ 0xc0, /* ##...... */
+ /*0a19:*/ 0xc0, /* ##...... */
+ /*0a1a:*/ 0xc0, /* ##...... */
+ /*0a1b:*/ 0xc0, /* ##...... */
+ /*0a1c:*/ 0xc0, /* ##...... */
+ /*0a1d:*/ 0xc0, /* ##...... */
+ /*0a1e:*/ 0xc0, /* ##...... */
+/* --- new character j (106) starting at offset 0x0a1f --- */
+ /*0a1f:*/ 6, 4, 24, 0, -5, /* width and bbox (w,h,x,y) */
+ /*0a24:*/ 0x30, /* ..##.... */
+ /*0a25:*/ 0x30, /* ..##.... */
+ /*0a26:*/ 0x30, /* ..##.... */
+ /*0a27:*/ 0x00, /* ........ */
+ /*0a28:*/ 0x00, /* ........ */
+ /*0a29:*/ 0x30, /* ..##.... */
+ /*0a2a:*/ 0x30, /* ..##.... */
+ /*0a2b:*/ 0x30, /* ..##.... */
+ /*0a2c:*/ 0x30, /* ..##.... */
+ /*0a2d:*/ 0x30, /* ..##.... */
+ /*0a2e:*/ 0x30, /* ..##.... */
+ /*0a2f:*/ 0x30, /* ..##.... */
+ /*0a30:*/ 0x30, /* ..##.... */
+ /*0a31:*/ 0x30, /* ..##.... */
+ /*0a32:*/ 0x30, /* ..##.... */
+ /*0a33:*/ 0x30, /* ..##.... */
+ /*0a34:*/ 0x30, /* ..##.... */
+ /*0a35:*/ 0x30, /* ..##.... */
+ /*0a36:*/ 0x30, /* ..##.... */
+ /*0a37:*/ 0x30, /* ..##.... */
+ /*0a38:*/ 0x30, /* ..##.... */
+ /*0a39:*/ 0x30, /* ..##.... */
+ /*0a3a:*/ 0xf0, /* ####.... */
+ /*0a3b:*/ 0xe0, /* ###..... */
+/* --- new character k (107) starting at offset 0x0a3c --- */
+ /*0a3c:*/ 12, 10, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a41:*/ 0xc0,0x00, /* ##.............. */
+ /*0a43:*/ 0xc0,0x00, /* ##.............. */
+ /*0a45:*/ 0xc0,0x00, /* ##.............. */
+ /*0a47:*/ 0xc0,0x00, /* ##.............. */
+ /*0a49:*/ 0xc0,0x00, /* ##.............. */
+ /*0a4b:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0a4d:*/ 0xc3,0x80, /* ##....###....... */
+ /*0a4f:*/ 0xc7,0x00, /* ##...###........ */
+ /*0a51:*/ 0xce,0x00, /* ##..###......... */
+ /*0a53:*/ 0xdc,0x00, /* ##.###.......... */
+ /*0a55:*/ 0xf8,0x00, /* #####........... */
+ /*0a57:*/ 0xfc,0x00, /* ######.......... */
+ /*0a59:*/ 0xce,0x00, /* ##..###......... */
+ /*0a5b:*/ 0xc6,0x00, /* ##...##......... */
+ /*0a5d:*/ 0xc7,0x00, /* ##...###........ */
+ /*0a5f:*/ 0xc3,0x80, /* ##....###....... */
+ /*0a61:*/ 0xc1,0x80, /* ##.....##....... */
+ /*0a63:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*0a65:*/ 0xc0,0xc0, /* ##......##...... */
+/* --- new character l (108) starting at offset 0x0a67 --- */
+ /*0a67:*/ 6, 2, 19, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a6c:*/ 0xc0, /* ##...... */
+ /*0a6d:*/ 0xc0, /* ##...... */
+ /*0a6e:*/ 0xc0, /* ##...... */
+ /*0a6f:*/ 0xc0, /* ##...... */
+ /*0a70:*/ 0xc0, /* ##...... */
+ /*0a71:*/ 0xc0, /* ##...... */
+ /*0a72:*/ 0xc0, /* ##...... */
+ /*0a73:*/ 0xc0, /* ##...... */
+ /*0a74:*/ 0xc0, /* ##...... */
+ /*0a75:*/ 0xc0, /* ##...... */
+ /*0a76:*/ 0xc0, /* ##...... */
+ /*0a77:*/ 0xc0, /* ##...... */
+ /*0a78:*/ 0xc0, /* ##...... */
+ /*0a79:*/ 0xc0, /* ##...... */
+ /*0a7a:*/ 0xc0, /* ##...... */
+ /*0a7b:*/ 0xc0, /* ##...... */
+ /*0a7c:*/ 0xc0, /* ##...... */
+ /*0a7d:*/ 0xc0, /* ##...... */
+ /*0a7e:*/ 0xc0, /* ##...... */
+/* --- new character m (109) starting at offset 0x0a7f --- */
+ /*0a7f:*/ 20, 16, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0a84:*/ 0xce,0x3c, /* ##..###...####.. */
+ /*0a86:*/ 0xff,0x7e, /* ########.######. */
+ /*0a88:*/ 0xe3,0xc7, /* ###...####...### */
+ /*0a8a:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a8c:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a8e:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a90:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a92:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a94:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a96:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a98:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a9a:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a9c:*/ 0xc1,0x83, /* ##.....##.....## */
+ /*0a9e:*/ 0xc1,0x83, /* ##.....##.....## */
+/* --- new character n (110) starting at offset 0x0aa0 --- */
+ /*0aa0:*/ 14, 10, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0aa5:*/ 0xce,0x00, /* ##..###......... */
+ /*0aa7:*/ 0xdf,0x80, /* ##.######....... */
+ /*0aa9:*/ 0xf1,0x80, /* ####...##....... */
+ /*0aab:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*0aad:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0aaf:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0ab1:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0ab3:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0ab5:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0ab7:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0ab9:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0abb:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0abd:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0abf:*/ 0xc0,0xc0, /* ##......##...... */
+/* --- new character o (111) starting at offset 0x0ac1 --- */
+ /*0ac1:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0ac6:*/ 0x1f,0x00, /* ...#####........ */
+ /*0ac8:*/ 0x3f,0x80, /* ..#######....... */
+ /*0aca:*/ 0x71,0xc0, /* .###...###...... */
+ /*0acc:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0ace:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0ad0:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0ad2:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0ad4:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0ad6:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0ad8:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0ada:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0adc:*/ 0x71,0xc0, /* .###...###...... */
+ /*0ade:*/ 0x3f,0x80, /* ..#######....... */
+ /*0ae0:*/ 0x1f,0x00, /* ...#####........ */
+/* --- new character p (112) starting at offset 0x0ae2 --- */
+ /*0ae2:*/ 14, 11, 19, 2, -5, /* width and bbox (w,h,x,y) */
+ /*0ae7:*/ 0xcf,0x00, /* ##..####........ */
+ /*0ae9:*/ 0xdf,0x80, /* ##.######....... */
+ /*0aeb:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0aed:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*0aef:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0af1:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0af3:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0af5:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0af7:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0af9:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0afb:*/ 0xe0,0xc0, /* ###.....##...... */
+ /*0afd:*/ 0xf1,0xc0, /* ####...###...... */
+ /*0aff:*/ 0xdf,0x80, /* ##.######....... */
+ /*0b01:*/ 0xcf,0x00, /* ##..####........ */
+ /*0b03:*/ 0xc0,0x00, /* ##.............. */
+ /*0b05:*/ 0xc0,0x00, /* ##.............. */
+ /*0b07:*/ 0xc0,0x00, /* ##.............. */
+ /*0b09:*/ 0xc0,0x00, /* ##.............. */
+ /*0b0b:*/ 0xc0,0x00, /* ##.............. */
+/* --- new character q (113) starting at offset 0x0b0d --- */
+ /*0b0d:*/ 14, 11, 19, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0b12:*/ 0x1e,0x60, /* ...####..##..... */
+ /*0b14:*/ 0x3f,0x60, /* ..######.##..... */
+ /*0b16:*/ 0x71,0xe0, /* .###...####..... */
+ /*0b18:*/ 0x60,0xe0, /* .##.....###..... */
+ /*0b1a:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0b1c:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0b1e:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0b20:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0b22:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0b24:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0b26:*/ 0x60,0xe0, /* .##.....###..... */
+ /*0b28:*/ 0x71,0xe0, /* .###...####..... */
+ /*0b2a:*/ 0x3f,0x60, /* ..######.##..... */
+ /*0b2c:*/ 0x1e,0x60, /* ...####..##..... */
+ /*0b2e:*/ 0x00,0x60, /* .........##..... */
+ /*0b30:*/ 0x00,0x60, /* .........##..... */
+ /*0b32:*/ 0x00,0x60, /* .........##..... */
+ /*0b34:*/ 0x00,0x60, /* .........##..... */
+ /*0b36:*/ 0x00,0x60, /* .........##..... */
+/* --- new character r (114) starting at offset 0x0b38 --- */
+ /*0b38:*/ 9, 6, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0b3d:*/ 0xcc, /* ##..##.. */
+ /*0b3e:*/ 0xdc, /* ##.###.. */
+ /*0b3f:*/ 0xfc, /* ######.. */
+ /*0b40:*/ 0xe0, /* ###..... */
+ /*0b41:*/ 0xc0, /* ##...... */
+ /*0b42:*/ 0xc0, /* ##...... */
+ /*0b43:*/ 0xc0, /* ##...... */
+ /*0b44:*/ 0xc0, /* ##...... */
+ /*0b45:*/ 0xc0, /* ##...... */
+ /*0b46:*/ 0xc0, /* ##...... */
+ /*0b47:*/ 0xc0, /* ##...... */
+ /*0b48:*/ 0xc0, /* ##...... */
+ /*0b49:*/ 0xc0, /* ##...... */
+ /*0b4a:*/ 0xc0, /* ##...... */
+/* --- new character s (115) starting at offset 0x0b4b --- */
+ /*0b4b:*/ 12, 10, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0b50:*/ 0x3e,0x00, /* ..#####......... */
+ /*0b52:*/ 0x7f,0x80, /* .########....... */
+ /*0b54:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0b56:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b58:*/ 0xc0,0x00, /* ##.............. */
+ /*0b5a:*/ 0xf8,0x00, /* #####........... */
+ /*0b5c:*/ 0x7f,0x00, /* .#######........ */
+ /*0b5e:*/ 0x0f,0x80, /* ....#####....... */
+ /*0b60:*/ 0x01,0xc0, /* .......###...... */
+ /*0b62:*/ 0x00,0xc0, /* ........##...... */
+ /*0b64:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b66:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*0b68:*/ 0xff,0x80, /* #########....... */
+ /*0b6a:*/ 0x3f,0x00, /* ..######........ */
+/* --- new character t (116) starting at offset 0x0b6c --- */
+ /*0b6c:*/ 8, 6, 18, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0b71:*/ 0x30, /* ..##.... */
+ /*0b72:*/ 0x30, /* ..##.... */
+ /*0b73:*/ 0x30, /* ..##.... */
+ /*0b74:*/ 0x30, /* ..##.... */
+ /*0b75:*/ 0xfc, /* ######.. */
+ /*0b76:*/ 0xfc, /* ######.. */
+ /*0b77:*/ 0x30, /* ..##.... */
+ /*0b78:*/ 0x30, /* ..##.... */
+ /*0b79:*/ 0x30, /* ..##.... */
+ /*0b7a:*/ 0x30, /* ..##.... */
+ /*0b7b:*/ 0x30, /* ..##.... */
+ /*0b7c:*/ 0x30, /* ..##.... */
+ /*0b7d:*/ 0x30, /* ..##.... */
+ /*0b7e:*/ 0x30, /* ..##.... */
+ /*0b7f:*/ 0x30, /* ..##.... */
+ /*0b80:*/ 0x30, /* ..##.... */
+ /*0b81:*/ 0x3c, /* ..####.. */
+ /*0b82:*/ 0x1c, /* ...###.. */
+/* --- new character u (117) starting at offset 0x0b83 --- */
+ /*0b83:*/ 14, 10, 14, 2, 0, /* width and bbox (w,h,x,y) */
+ /*0b88:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b8a:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b8c:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b8e:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b90:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b92:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b94:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b96:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b98:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b9a:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0b9c:*/ 0xc1,0xc0, /* ##.....###...... */
+ /*0b9e:*/ 0x63,0xc0, /* .##...####...... */
+ /*0ba0:*/ 0x7e,0xc0, /* .######.##...... */
+ /*0ba2:*/ 0x1c,0xc0, /* ...###..##...... */
+/* --- new character v (118) starting at offset 0x0ba4 --- */
+ /*0ba4:*/ 13, 11, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0ba9:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0bab:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0bad:*/ 0xc0,0x60, /* ##.......##..... */
+ /*0baf:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0bb1:*/ 0x60,0xc0, /* .##.....##...... */
+ /*0bb3:*/ 0x71,0xc0, /* .###...###...... */
+ /*0bb5:*/ 0x31,0x80, /* ..##...##....... */
+ /*0bb7:*/ 0x31,0x80, /* ..##...##....... */
+ /*0bb9:*/ 0x1b,0x00, /* ...##.##........ */
+ /*0bbb:*/ 0x1b,0x00, /* ...##.##........ */
+ /*0bbd:*/ 0x1b,0x00, /* ...##.##........ */
+ /*0bbf:*/ 0x0e,0x00, /* ....###......... */
+ /*0bc1:*/ 0x0e,0x00, /* ....###......... */
+ /*0bc3:*/ 0x0e,0x00, /* ....###......... */
+/* --- new character w (119) starting at offset 0x0bc5 --- */
+ /*0bc5:*/ 18, 18, 14, 0, 0, /* width and bbox (w,h,x,y) */
+ /*0bca:*/ 0xc0,0xc0,0xc0, /* ##......##......##...... */
+ /*0bcd:*/ 0xc0,0xc0,0xc0, /* ##......##......##...... */
+ /*0bd0:*/ 0x61,0xe1,0x80, /* .##....####....##....... */
+ /*0bd3:*/ 0x61,0xe1,0x80, /* .##....####....##....... */
+ /*0bd6:*/ 0x61,0xe1,0x80, /* .##....####....##....... */
+ /*0bd9:*/ 0x31,0x23,0x00, /* ..##...#..#...##........ */
+ /*0bdc:*/ 0x33,0x33,0x00, /* ..##..##..##..##........ */
+ /*0bdf:*/ 0x33,0x33,0x00, /* ..##..##..##..##........ */
+ /*0be2:*/ 0x1b,0x36,0x00, /* ...##.##..##.##......... */
+ /*0be5:*/ 0x1a,0x16,0x00, /* ...##.#....#.##......... */
+ /*0be8:*/ 0x1e,0x1e,0x00, /* ...####....####......... */
+ /*0beb:*/ 0x0e,0x1c,0x00, /* ....###....###.......... */
+ /*0bee:*/ 0x0c,0x0c,0x00, /* ....##......##.......... */
+ /*0bf1:*/ 0x0c,0x0c,0x00, /* ....##......##.......... */
+/* --- new character x (120) starting at offset 0x0bf4 --- */
+ /*0bf4:*/ 12, 10, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0bf9:*/ 0xc0,0xc0, /* ##......##...... */
+ /*0bfb:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0bfd:*/ 0x61,0x80, /* .##....##....... */
+ /*0bff:*/ 0x33,0x00, /* ..##..##........ */
+ /*0c01:*/ 0x3f,0x00, /* ..######........ */
+ /*0c03:*/ 0x1e,0x00, /* ...####......... */
+ /*0c05:*/ 0x0c,0x00, /* ....##.......... */
+ /*0c07:*/ 0x1e,0x00, /* ...####......... */
+ /*0c09:*/ 0x1e,0x00, /* ...####......... */
+ /*0c0b:*/ 0x33,0x00, /* ..##..##........ */
+ /*0c0d:*/ 0x73,0x80, /* .###..###....... */
+ /*0c0f:*/ 0x61,0x80, /* .##....##....... */
+ /*0c11:*/ 0xe1,0xc0, /* ###....###...... */
+ /*0c13:*/ 0xc0,0xc0, /* ##......##...... */
+/* --- new character y (121) starting at offset 0x0c15 --- */
+ /*0c15:*/ 13, 12, 19, 0, -5, /* width and bbox (w,h,x,y) */
+ /*0c1a:*/ 0xc0,0x30, /* ##........##.... */
+ /*0c1c:*/ 0xc0,0x30, /* ##........##.... */
+ /*0c1e:*/ 0x60,0x30, /* .##.......##.... */
+ /*0c20:*/ 0x70,0x60, /* .###.....##..... */
+ /*0c22:*/ 0x30,0x60, /* ..##.....##..... */
+ /*0c24:*/ 0x38,0xe0, /* ..###...###..... */
+ /*0c26:*/ 0x18,0xc0, /* ...##...##...... */
+ /*0c28:*/ 0x18,0xc0, /* ...##...##...... */
+ /*0c2a:*/ 0x0d,0x80, /* ....##.##....... */
+ /*0c2c:*/ 0x0d,0x80, /* ....##.##....... */
+ /*0c2e:*/ 0x07,0x80, /* .....####....... */
+ /*0c30:*/ 0x07,0x00, /* .....###........ */
+ /*0c32:*/ 0x03,0x00, /* ......##........ */
+ /*0c34:*/ 0x03,0x00, /* ......##........ */
+ /*0c36:*/ 0x06,0x00, /* .....##......... */
+ /*0c38:*/ 0x06,0x00, /* .....##......... */
+ /*0c3a:*/ 0x0c,0x00, /* ....##.......... */
+ /*0c3c:*/ 0x3c,0x00, /* ..####.......... */
+ /*0c3e:*/ 0x38,0x00, /* ..###........... */
+/* --- new character z (122) starting at offset 0x0c40 --- */
+ /*0c40:*/ 12, 10, 14, 1, 0, /* width and bbox (w,h,x,y) */
+ /*0c45:*/ 0xff,0xc0, /* ##########...... */
+ /*0c47:*/ 0xff,0xc0, /* ##########...... */
+ /*0c49:*/ 0x01,0x80, /* .......##....... */
+ /*0c4b:*/ 0x03,0x00, /* ......##........ */
+ /*0c4d:*/ 0x07,0x00, /* .....###........ */
+ /*0c4f:*/ 0x0e,0x00, /* ....###......... */
+ /*0c51:*/ 0x0c,0x00, /* ....##.......... */
+ /*0c53:*/ 0x1c,0x00, /* ...###.......... */
+ /*0c55:*/ 0x38,0x00, /* ..###........... */
+ /*0c57:*/ 0x30,0x00, /* ..##............ */
+ /*0c59:*/ 0x60,0x00, /* .##............. */
+ /*0c5b:*/ 0xe0,0x00, /* ###............. */
+ /*0c5d:*/ 0xff,0xc0, /* ##########...... */
+ /*0c5f:*/ 0xff,0xc0, /* ##########...... */
+/* --- new character braceleft (123) starting at offset 0x0c61 --- */
+ /*0c61:*/ 8, 6, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0c66:*/ 0x0c, /* ....##.. */
+ /*0c67:*/ 0x18, /* ...##... */
+ /*0c68:*/ 0x30, /* ..##.... */
+ /*0c69:*/ 0x30, /* ..##.... */
+ /*0c6a:*/ 0x30, /* ..##.... */
+ /*0c6b:*/ 0x30, /* ..##.... */
+ /*0c6c:*/ 0x30, /* ..##.... */
+ /*0c6d:*/ 0x30, /* ..##.... */
+ /*0c6e:*/ 0x30, /* ..##.... */
+ /*0c6f:*/ 0x30, /* ..##.... */
+ /*0c70:*/ 0x60, /* .##..... */
+ /*0c71:*/ 0xc0, /* ##...... */
+ /*0c72:*/ 0xc0, /* ##...... */
+ /*0c73:*/ 0x60, /* .##..... */
+ /*0c74:*/ 0x30, /* ..##.... */
+ /*0c75:*/ 0x30, /* ..##.... */
+ /*0c76:*/ 0x30, /* ..##.... */
+ /*0c77:*/ 0x30, /* ..##.... */
+ /*0c78:*/ 0x30, /* ..##.... */
+ /*0c79:*/ 0x30, /* ..##.... */
+ /*0c7a:*/ 0x30, /* ..##.... */
+ /*0c7b:*/ 0x30, /* ..##.... */
+ /*0c7c:*/ 0x18, /* ...##... */
+ /*0c7d:*/ 0x0c, /* ....##.. */
+/* --- new character bar (124) starting at offset 0x0c7e --- */
+ /*0c7e:*/ 6, 2, 24, 2, -5, /* width and bbox (w,h,x,y) */
+ /*0c83:*/ 0xc0, /* ##...... */
+ /*0c84:*/ 0xc0, /* ##...... */
+ /*0c85:*/ 0xc0, /* ##...... */
+ /*0c86:*/ 0xc0, /* ##...... */
+ /*0c87:*/ 0xc0, /* ##...... */
+ /*0c88:*/ 0xc0, /* ##...... */
+ /*0c89:*/ 0xc0, /* ##...... */
+ /*0c8a:*/ 0xc0, /* ##...... */
+ /*0c8b:*/ 0xc0, /* ##...... */
+ /*0c8c:*/ 0xc0, /* ##...... */
+ /*0c8d:*/ 0xc0, /* ##...... */
+ /*0c8e:*/ 0xc0, /* ##...... */
+ /*0c8f:*/ 0xc0, /* ##...... */
+ /*0c90:*/ 0xc0, /* ##...... */
+ /*0c91:*/ 0xc0, /* ##...... */
+ /*0c92:*/ 0xc0, /* ##...... */
+ /*0c93:*/ 0xc0, /* ##...... */
+ /*0c94:*/ 0xc0, /* ##...... */
+ /*0c95:*/ 0xc0, /* ##...... */
+ /*0c96:*/ 0xc0, /* ##...... */
+ /*0c97:*/ 0xc0, /* ##...... */
+ /*0c98:*/ 0xc0, /* ##...... */
+ /*0c99:*/ 0xc0, /* ##...... */
+ /*0c9a:*/ 0xc0, /* ##...... */
+/* --- new character braceright (125) starting at offset 0x0c9b --- */
+ /*0c9b:*/ 8, 6, 24, 1, -5, /* width and bbox (w,h,x,y) */
+ /*0ca0:*/ 0xc0, /* ##...... */
+ /*0ca1:*/ 0x60, /* .##..... */
+ /*0ca2:*/ 0x30, /* ..##.... */
+ /*0ca3:*/ 0x30, /* ..##.... */
+ /*0ca4:*/ 0x30, /* ..##.... */
+ /*0ca5:*/ 0x30, /* ..##.... */
+ /*0ca6:*/ 0x30, /* ..##.... */
+ /*0ca7:*/ 0x30, /* ..##.... */
+ /*0ca8:*/ 0x30, /* ..##.... */
+ /*0ca9:*/ 0x30, /* ..##.... */
+ /*0caa:*/ 0x18, /* ...##... */
+ /*0cab:*/ 0x0c, /* ....##.. */
+ /*0cac:*/ 0x0c, /* ....##.. */
+ /*0cad:*/ 0x18, /* ...##... */
+ /*0cae:*/ 0x30, /* ..##.... */
+ /*0caf:*/ 0x30, /* ..##.... */
+ /*0cb0:*/ 0x30, /* ..##.... */
+ /*0cb1:*/ 0x30, /* ..##.... */
+ /*0cb2:*/ 0x30, /* ..##.... */
+ /*0cb3:*/ 0x30, /* ..##.... */
+ /*0cb4:*/ 0x30, /* ..##.... */
+ /*0cb5:*/ 0x30, /* ..##.... */
+ /*0cb6:*/ 0x60, /* .##..... */
+ /*0cb7:*/ 0xc0, /* ##...... */
+/* --- new character asciitilde (126) starting at offset 0x0cb8 --- */
+ /*0cb8:*/ 14, 10, 4, 2, 5, /* width and bbox (w,h,x,y) */
+ /*0cbd:*/ 0x70,0xc0, /* .###....##...... */
+ /*0cbf:*/ 0xfc,0xc0, /* ######..##...... */
+ /*0cc1:*/ 0xcf,0xc0, /* ##..######...... */
+ /*0cc3:*/ 0xc3,0x80, /* ##....###....... */
+};
+static const uint16_t font_helvR24_offsets[] = {
+0x0000 /* space */,
+ 0x0006 /* exclam */,
+ 0x001e /* quotedbl */,
+ 0x0029 /* numbersign */,
+ 0x0050 /* dollar */,
+ 0x007f /* percent */,
+ 0x00ba /* ampersand */,
+ 0x00e3 /* quotesingle */,
+ 0x00ee /* parenleft */,
+ 0x010b /* parenright */,
+ 0x0128 /* asterisk */,
+ 0x0134 /* plus */,
+ 0x0151 /* comma */,
+ 0x015c /* hyphen */,
+ 0x0163 /* period */,
+ 0x016b /* slash */,
+ 0x0183 /* zero */,
+ 0x01ac /* one */,
+ 0x01c3 /* two */,
+ 0x01ec /* three */,
+ 0x0215 /* four */,
+ 0x023e /* five */,
+ 0x0267 /* six */,
+ 0x0290 /* seven */,
+ 0x02b9 /* eight */,
+ 0x02e2 /* nine */,
+ 0x030b /* colon */,
+ 0x031e /* semicolon */,
+ 0x0334 /* less */,
+ 0x0351 /* equal */,
+ 0x0362 /* greater */,
+ 0x037f /* question */,
+ 0x03aa /* at */,
+ 0x03f4 /* A */,
+ 0x041f /* B */,
+ 0x044a /* C */,
+ 0x0475 /* D */,
+ 0x04a0 /* E */,
+ 0x04cb /* F */,
+ 0x04f6 /* G */,
+ 0x0521 /* H */,
+ 0x054c /* I */,
+ 0x0564 /* J */,
+ 0x058f /* K */,
+ 0x05ba /* L */,
+ 0x05e5 /* M */,
+ 0x0623 /* N */,
+ 0x064e /* O */,
+ 0x0679 /* P */,
+ 0x06a4 /* Q */,
+ 0x06cf /* R */,
+ 0x06fa /* S */,
+ 0x0725 /* T */,
+ 0x0750 /* U */,
+ 0x077b /* V */,
+ 0x07a6 /* W */,
+ 0x07e4 /* X */,
+ 0x080f /* Y */,
+ 0x083a /* Z */,
+ 0x0865 /* bracketleft */,
+ 0x0882 /* backslash */,
+ 0x089a /* bracketright */,
+ 0x08b7 /* asciicircum */,
+ 0x08ce /* underscore */,
+ 0x08d7 /* grave */,
+ 0x08e0 /* a */,
+ 0x0901 /* b */,
+ 0x092c /* c */,
+ 0x094d /* d */,
+ 0x0978 /* e */,
+ 0x0999 /* f */,
+ 0x09b1 /* g */,
+ 0x09dc /* h */,
+ 0x0a07 /* i */,
+ 0x0a1f /* j */,
+ 0x0a3c /* k */,
+ 0x0a67 /* l */,
+ 0x0a7f /* m */,
+ 0x0aa0 /* n */,
+ 0x0ac1 /* o */,
+ 0x0ae2 /* p */,
+ 0x0b0d /* q */,
+ 0x0b38 /* r */,
+ 0x0b4b /* s */,
+ 0x0b6c /* t */,
+ 0x0b83 /* u */,
+ 0x0ba4 /* v */,
+ 0x0bc5 /* w */,
+ 0x0bf4 /* x */,
+ 0x0c15 /* y */,
+ 0x0c40 /* z */,
+ 0x0c61 /* braceleft */,
+ 0x0c7e /* bar */,
+ 0x0c9b /* braceright */,
+ 0x0cb8 /* asciitilde */,
+ 0xffff /* (no glyph) */
+};
+const struct fb_font font_helvR24 = {
+ .height = 27,
+ .ascent = 22,
+ .firstchar = 32, /* space */
+ .lastchar = 127, /* ? */
+ .chardata = font_helvR24_data,
+ .charoffs = font_helvR24_offsets,
+};
diff --git a/Src/osmolib/src/target/firmware/include/calypso/sim.h b/Src/osmolib/src/target/firmware/include/calypso/sim.h
index b2a2164..5e33bdb 100644..100755
--- a/Src/osmolib/src/target/firmware/include/calypso/sim.h
+++ b/Src/osmolib/src/target/firmware/include/calypso/sim.h
@@ -147,8 +147,6 @@
/* 1 = SIM card insertion/extraction */
-#define SIM_DEBUG_OUTPUTDELAY 200 /* Output delay to minimize stress with some uart bugs */
-#define SIM_DEBUG 0 /* 0=Debug messages are off / 1=Debug messages are on */
#define SIM_OPERATION_DELAY 100 /* Time between operations like reset, vcc apply ect... */
@@ -164,24 +162,14 @@ void calypso_sim_powerdown(void); /* Powerdown simcard */
#define SIM_APDU_PUT 0 /* Transmit a data body to the card */
#define SIM_APDU_GET 1 /* Fetch data from the card eg. GET RESOPNSE */
-/* Transceive T0 Apdu to sim acording to GSM 11.11 Page 34 */
-int calypso_sim_transceive(uint8_t cla, /* Class (in GSM context mostly 0xA0 */
- uint8_t ins, /* Instruction */
- uint8_t p1, /* First parameter */
- uint8_t p2, /* Second parameter */
- uint8_t p3le, /* Length of the data that should be transceived */
- uint8_t *data, /* Data payload */
- uint8_t *status, /* Status word (2 byte array, see note 1) */
- uint8_t mode); /* Mode of operation: 1=GET, 0=PUT */
- /* Note 1: You can use a null-pointer (0) if you are not interested in
- the status word */
+void calypso_sim_init(void); /* Initialize simcard interface */
-/* Transmission of raw data */
-int calypso_sim_receive(uint8_t *data); /* Receive raw data through the sim interface */
-int calypso_sim_transmit(uint8_t *data, int length); /* Transmit raw data through the sim interface */
+/* handling sim events */
+void sim_handler(void);
-void calypso_sim_init(void); /* Initialize simcard interface */
+/* simm command from layer 23 */
+void sim_apdu(uint16_t len, uint8_t *data);
/* Known Bugs:
diff --git a/Src/osmolib/src/target/firmware/include/comm/timer.h b/Src/osmolib/src/target/firmware/include/comm/timer.h
index db7d1a5..1996f66 100644
--- a/Src/osmolib/src/target/firmware/include/comm/timer.h
+++ b/Src/osmolib/src/target/firmware/include/comm/timer.h
@@ -25,19 +25,21 @@
#include <osmocom/core/linuxlist.h>
+#define HZ 100
+
/**
* Timer management:
* - Create a struct osmo_timer_list
- * - Fill out timeout and use add_timer or
- * use schedule_timer to schedule a timer in
+ * - Fill out timeout and use osmo_timer_add or
+ * use osmo_timer_schedule to schedule a timer in
* x seconds and microseconds from now...
- * - Use del_timer to remove the timer
+ * - Use osmo_timer_del to remove the timer
*
* Internally:
* - We hook into select.c to give a timeval of the
* nearest timer. On already passed timers we give
* it a 0 to immediately fire after the select
- * - update_timers will call the callbacks and remove
+ * - osmo_timers_update will call the callbacks and remove
* the timers.
*
*/
@@ -58,18 +60,17 @@ extern unsigned long volatile jiffies;
/**
* timer management
*/
-void add_timer(struct osmo_timer_list *timer);
-void schedule_timer(struct osmo_timer_list *timer, int miliseconds);
-void del_timer(struct osmo_timer_list *timer);
-int timer_pending(struct osmo_timer_list *timer);
+void osmo_timer_add(struct osmo_timer_list *timer);
+void osmo_timer_schedule(struct osmo_timer_list *timer, int miliseconds);
+void osmo_timer_del(struct osmo_timer_list *timer);
+int osmo_timer_pending(struct osmo_timer_list *timer);
/**
* internal timer list management
*/
-void prepare_timers(void);
-int update_timers(void);
-int timer_check(void);
+int osmo_timers_update(void);
+int osmo_timers_check(void);
void timer_init(void);
diff --git a/Src/osmolib/src/target/firmware/include/fb/fb_bw8.h b/Src/osmolib/src/target/firmware/include/fb/fb_bw8.h
new file mode 100644
index 0000000..c77fa71
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/include/fb/fb_bw8.h
@@ -0,0 +1,51 @@
+#ifndef FB_BW8_H
+#define FB_BW8_H
+
+/* 8bit monochrome framebuffer, organized with 8 stacked pixels
+ per byte, backed by local memory. fb_bw8.c lists functions that
+ are common to simmilar organized displays. */
+
+/*
+ Sketch of Memory Layout
+ Left Upper Corner of Display
+
+ col0 col2
+ col1
+ +-------------
+ 1st row: | A0 B0 C0
+ 2nd row: | A1 B1 C1
+ ...
+ 7th row: | A6 B6 C6
+ 8th row: | A7 B7 C7
+ 9th row: | Q0 R0 S0
+ 10th row: | Q1 R1 S1 ...
+ ...
+
+ Backing store (and internal display memory?) looks like...
+
+ uint8_t mem[] = { A, B, C, .... Q, R, S, ... }
+
+ We work on a in-memory copy of the framebuffer and only
+ update the physical display on demand. The damage window
+ has two corners, left upper inclusive x1,y1 and right
+ lower x2,y2 exclusive. So dirty pixels are defined to
+ be x1 <= x_pixel < x2 and y1 <= y_pixel < y2.
+*/
+
+/* data specific to a bw8-type framebuffer as described above */
+
+struct fb_bw8 {
+ uint8_t *mem; /* set to backingstore memory */
+ uint16_t damage_x1,damage_y1; /* current damage window, ul */
+ uint16_t damage_x2,damage_y2; /* current damage window, lr */
+};
+
+extern struct fb_bw8 *fb_bw8; /* symbol defined by the specific LCD driver */
+
+extern void fb_bw8_clear();
+extern void fb_bw8_boxto(uint16_t x,uint16_t y); /* draw a box from cursor to x,y */
+extern void fb_bw8_lineto(uint16_t x,uint16_t y); /* draw a line from cursor to x,y */
+
+extern int fb_bw8_putstr(char *str,int maxwidth);
+
+#endif
diff --git a/Src/osmolib/src/target/firmware/include/fb/fb_rgb332.h b/Src/osmolib/src/target/firmware/include/fb/fb_rgb332.h
new file mode 100644
index 0000000..4df44e4
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/include/fb/fb_rgb332.h
@@ -0,0 +1,47 @@
+#ifndef FB_RGB332_H
+#define FB_RGB332_H
+
+/* RGB framebuffer with 1 byte per pixel, bits mapped as RRRGGGBB */
+
+struct fb_rgb332 {
+ uint8_t *mem; /* set to backingstore memory */
+ uint16_t damage_x1,damage_y1; /* current damage window, ul (incl) */
+ uint16_t damage_x2,damage_y2; /* current damage window, lr (excl) */
+};
+
+extern void fb_rgb332_clear();
+
+/* draw a box from cursor to x,y */
+extern void fb_rgb332_boxto(uint16_t x,uint16_t y);
+/* draw a line from cursor to x,y */
+extern void fb_rgb332_lineto(uint16_t x,uint16_t y);
+
+/* put string str onto framebuffer with line (bottom
+ left pixel of, e.g. "m") starting at cursor.
+ Maximum width consumed is maxwidth, actual width
+ needed is returned */
+extern int fb_rgb332_putstr(char *str,int maxwidth);
+
+extern struct fb_rgb332 *fb_rgb332;
+
+/* this convenience function can be used if you choose to
+ * back a RGB565 display with a RGB332 framebuffer to conserve
+ * ARM memory. It converts a rgb332 value to rgb565 as indicated
+ * in the comments. */
+
+static inline uint16_t
+rgb332_to_565(uint8_t rgb332){
+
+ uint8_t red = (rgb332 & 0xe0) >> 5 ; // rrr. .... -> .... .rrr
+ uint8_t green = ((rgb332 & 0x1c) >> 2); // ...g gg.. -> .... .ggg
+ uint8_t blue = rgb332 & 0x03; // .... ..bb -> .... ..bb
+
+ red = (red << 2) | (red >> 1); /* .....210 -> ...21021 */
+ green = (green << 3) | (green); /* .....210 -> ..210210 */
+ blue = (blue << 3) | (blue << 1) | (blue >> 1); /* ......10 -> ...10101 */
+
+ /* rrrrrggg gggbbbbb */
+ return (red << 11) | (green << 5) | blue;
+}
+
+#endif
diff --git a/Src/osmolib/src/target/firmware/include/fb/font.h b/Src/osmolib/src/target/firmware/include/fb/font.h
new file mode 100644
index 0000000..40a6974
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/include/fb/font.h
@@ -0,0 +1,81 @@
+#ifndef _FB_FONT_H
+#define _FB_FONT_H
+
+#include <stdint.h>
+#include <unistd.h>
+
+/*
+ Example:
+ Font Helvetica 14
+
+
+ Character W ('X' and '.' is the character font data)
+
+ X.....X......&...
+ X.....X......X...
+ X....X.X.....X...
+ .X...X.X....X....
+ .X...X.X....X....
+ .X...X.X....X....
+ ..X.X....X.X.....
+ ..X.X....X.X.....
+ ..X.X....X.X.....
+ ...X......X......
+ @%..X......X...$..
+ <---dwidth---->
+
+ @ is the cursor position (origin) for this character
+ $ is the cursor position (origin) for the next character
+ % is the character boundingbox origin,
+ & is the character boundingbox top right corner
+
+ */
+
+/* data for char c is found by getting the index into the
+ chardata array from the charoffs array.
+
+ if charoffs[c] == FB_FONT_NOCHAR, then this glyph does
+ not exist! Better use the convenience function fb_font_get_char below! */
+
+#define FB_FONT_NOCHAR 0xffff
+
+struct fb_font {
+ int8_t height; /* total height of font */
+ int8_t ascent; /* topmost pixel is "ascend" above
+ current cursor position y */
+ uint8_t firstchar,lastchar; /* range of characters in font (iso8859-1) */
+ uint8_t const *chardata;
+ uint16_t const *charoffs; /* byte offsets relative to chardata */
+ uint8_t const *widths; /* widths for characters */
+};
+
+struct fb_char {
+ int8_t width;
+ int8_t bbox_w,bbox_h,bbox_x,bbox_y;
+ uint8_t data[0];
+};
+
+/* there are currently 6 fonts available, Helvetica 8, 14, 24 point
+ in bold and regular shapes. The following enum has to match the
+ order of the array fb_fonts in framebuffer.c!
+*/
+
+enum fb_font_id {
+// FB_FONT_4X6,
+// FB_FONT_5X8,
+ FB_FONT_HELVR08,
+// FB_FONT_HELVR14
+// FB_FONT_HELVR24,
+// FB_FONT_HELVB08,
+ FB_FONT_HELVB14,
+// FB_FONT_HELVB24,
+ FB_FONT_C64,
+};
+
+extern const struct fb_font *fb_fonts[]; // note: has to match fb_font_id enum!
+
+extern const struct fb_char *
+fb_font_get_char(const struct fb_font *fnt,unsigned char c);
+
+#endif
+
diff --git a/Src/osmolib/src/target/firmware/include/fb/framebuffer.h b/Src/osmolib/src/target/firmware/include/fb/framebuffer.h
new file mode 100644
index 0000000..e765b36
--- /dev/null
+++ b/Src/osmolib/src/target/firmware/include/fb/framebuffer.h
@@ -0,0 +1,128 @@
+#ifndef _FB_FRAMEBUFFER_H
+#define _FB_FRAMEBUFFER_H
+
+#include <fb/font.h>
+#include <stdint.h>
+
+/* color is encoded as <special><red><green><blue> */
+/* if a color is "special", then the RGB components most likely
+ don't make sense. Use "special" colours when you have to
+ mask out bits with transparency or you have to encode
+ colours in a fixed color palette... */
+
+#define FB_COLOR_WHITE 0x00ffffffU
+#define FB_COLOR_BLACK 0x00000000U
+#define FB_COLOR_TRANSP 0x01ffffffU
+
+#define FB_COLOR_RGB(r,g,b) ((((r) & 0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))
+#define FB_COLOR_RED FB_COLOR_RGB(0xff,0x00,0x00)
+#define FB_COLOR_GREEN FB_COLOR_RGB(0x00,0xff,0x00)
+#define FB_COLOR_BLUE FB_COLOR_RGB(0x00,0x00,0xff)
+
+/* encode */
+
+/* decode */
+#define FB_COLOR_IS_SPECIAL(v) (!!((v) & 0xff000000U))
+#define FB_COLOR_TO_R(v) (((v)>>16) & 0xff)
+#define FB_COLOR_TO_G(v) (((v)>> 8) & 0xff)
+#define FB_COLOR_TO_B(v) ( (v) & 0xff)
+
+struct framebuffer {
+ char name[8]; // keep it short!
+ void (*init)(); // (re)initialize
+ void (*clear)(); // clear display
+ void (*boxto)(uint16_t x,uint16_t y); // draw box to xy
+ void (*lineto)(uint16_t x,uint16_t y); // draw line to xy
+ int (*putstr)(char *c,int maxwidth); // put text in current font to fb
+ void (*flush)(); // flush changes
+
+ uint16_t width,height; // width/height of fb
+ uint16_t cursor_x,cursor_y; // current cursor
+ uint32_t fg_color,bg_color; // current fg/bg color
+ enum fb_font_id font; // current font
+};
+
+/* there is a single framebuffer, the specific driver defines
+ the "framebuffer" symbol */
+extern struct framebuffer *framebuffer;
+
+static inline void
+fb_init(){
+ framebuffer->init();
+}
+
+static inline void
+fb_clear(){
+ framebuffer->clear();
+}
+
+static inline void
+fb_boxto(uint16_t x,uint16_t y){
+ framebuffer->boxto(x,y);
+}
+
+static inline void
+fb_lineto(uint16_t x,uint16_t y){
+ framebuffer->lineto(x,y);
+}
+
+static inline int
+fb_putstr(char *str,int maxwidth){
+ return framebuffer->putstr(str,maxwidth);
+}
+
+static inline void
+fb_flush(){
+ framebuffer->flush();
+}
+
+static inline void
+fb_gotoxy(uint16_t x,uint16_t y){
+ framebuffer->cursor_x = x;
+ framebuffer->cursor_y = y;
+}
+
+static inline void
+fb_setfg(uint32_t color){
+ framebuffer->fg_color = color;
+}
+
+static inline void
+fb_setbg(uint32_t color){
+ framebuffer->bg_color = color;
+}
+
+static inline void
+fb_setfont(enum fb_font_id fid){
+ framebuffer->font = fid;
+}
+
+/* utility function: limit coordinates to area of framebuffer */
+static inline void
+fb_limit_fb_range(uint16_t *x,uint16_t *y){
+ if(*x >= framebuffer->width)
+ *x = framebuffer->width - 1;
+ if(*y >= framebuffer->height)
+ *y = framebuffer->height - 1;
+}
+
+/* utility function: limit box coordinates to area of framebuffer
+ and make sure that x1y1 is left upper edge, x2y2 is right lower */
+static inline void
+fb_sanitize_box(uint16_t *x1,uint16_t *y1,uint16_t *x2,uint16_t *y2){
+ fb_limit_fb_range(x1,y1);
+ fb_limit_fb_range(x2,y2);
+ if(*x1 > *x2){
+ uint16_t tmp = *x1;
+ *x1 = *x2;
+ *x2 = tmp;
+ }
+ if(*y1 > *y2){
+ uint16_t tmp = *y1;
+ *y1 = *y2;
+ *y2 = tmp;
+ }
+}
+
+#endif
+
diff --git a/Src/osmolib/src/target/firmware/include/layer1/async.h b/Src/osmolib/src/target/firmware/include/layer1/async.h
index a9fa08d..de996a6 100644
--- a/Src/osmolib/src/target/firmware/include/layer1/async.h
+++ b/Src/osmolib/src/target/firmware/include/layer1/async.h
@@ -44,6 +44,9 @@ void l1a_mftask_enable(enum mframe_task task);
/* Disable a repeating multiframe task */
void l1a_mftask_disable(enum mframe_task task);
+/* Set the mask for repeating multiframe tasks */
+void l1a_mftask_set(uint32_t tasks);
+
/* Set TCH mode */
uint8_t l1a_tch_mode_set(uint8_t mode);
diff --git a/Src/osmolib/src/target/firmware/include/layer1/l23_api.h b/Src/osmolib/src/target/firmware/include/layer1/l23_api.h
index 9b10b62..e4a3fd0 100644
--- a/Src/osmolib/src/target/firmware/include/layer1/l23_api.h
+++ b/Src/osmolib/src/target/firmware/include/layer1/l23_api.h
@@ -6,9 +6,12 @@
#include <l1ctl_proto.h>
void l1a_l23api_init(void);
+void l1a_l23_handler(void);
void l1_queue_for_l2(struct msgb *msg);
struct msgb *l1ctl_msgb_alloc(uint8_t msg_type);
struct msgb *l1_create_l2_msg(int msg_type, uint32_t fn, uint16_t snr, uint16_t arfcn);
+extern void (*l1a_l23_tx_cb)(struct msgb *msg);
+void l1a_l23_rx(uint8_t dlci, struct msgb *msg);
void l1ctl_tx_reset(uint8_t msg_type, uint8_t reset_type);
diff --git a/Src/osmolib/src/target/firmware/include/layer1/sync.h b/Src/osmolib/src/target/firmware/include/layer1/sync.h
index aa03c82..dae85a1 100644
--- a/Src/osmolib/src/target/firmware/include/layer1/sync.h
+++ b/Src/osmolib/src/target/firmware/include/layer1/sync.h
@@ -151,6 +151,7 @@ struct l1s_state {
uint8_t pos;
uint8_t running;
uint16_t band_arfcn[64];
+ uint8_t tn[64];
uint8_t level[64];
} neigh_pm;
};
diff --git a/Src/osmolib/src/target/firmware/include/rf/trf6151.h b/Src/osmolib/src/target/firmware/include/rf/trf6151.h
index f0891b6..c1eaf3b 100644
--- a/Src/osmolib/src/target/firmware/include/rf/trf6151.h
+++ b/Src/osmolib/src/target/firmware/include/rf/trf6151.h
@@ -22,7 +22,9 @@ int trf6151_set_gain(uint8_t dbm);
uint8_t trf6151_get_gain(void);
/* Request the PLL to be tuned to the given frequency */
-void trf6151_set_arfcn(uint16_t arfcn, int uplink);
+/* arfcn must have ARFCN_UPLINK flag set if you want uplink ! */
+/* tx selects the TX path only and doesn't set UL band ! */
+void trf6151_set_arfcn(uint16_t arfcn, int tx);
enum trf6151_mode {
TRF6151_IDLE,
diff --git a/Src/osmolib/src/target/firmware/layer1/l23_api.c b/Src/osmolib/src/target/firmware/layer1/l23_api.c
index 11f07cd..1c4459e 100644
--- a/Src/osmolib/src/target/firmware/layer1/l23_api.c
+++ b/Src/osmolib/src/target/firmware/layer1/l23_api.c
@@ -29,6 +29,8 @@
#include <debug.h>
#include <byteorder.h>
+#include <asm/system.h>
+
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <comm/sercomm.h>
@@ -38,18 +40,28 @@
#include <layer1/mframe_sched.h>
#include <layer1/prim.h>
#include <layer1/tpu_window.h>
+#include <layer1/sched_gsmtime.h>
#include <abb/twl3025.h>
#include <rf/trf6151.h>
+#include <calypso/sim.h>
+#include <calypso/dsp.h>
#include <l1ctl_proto.h>
/* the size we will allocate struct msgb* for HDLC */
#define L3_MSG_HEAD 4
-#define L3_MSG_SIZE (sizeof(struct l1ctl_hdr)+sizeof(struct l1ctl_info_dl)+sizeof(struct l1ctl_traffic_ind) + L3_MSG_HEAD)
+#define L3_MSG_DATA 200
+#define L3_MSG_SIZE (L3_MSG_HEAD + sizeof(struct l1ctl_hdr) + L3_MSG_DATA)
+
+void (*l1a_l23_tx_cb)(struct msgb *msg) = NULL;
void l1_queue_for_l2(struct msgb *msg)
{
+ if (l1a_l23_tx_cb) {
+ l1a_l23_tx_cb(msg);
+ return;
+ }
/* forward via serial for now */
sercomm_sendmsg(SC_DLCI_L1A_L23, msg);
}
@@ -395,7 +407,7 @@ static void l1ctl_rx_pm_req(struct msgb *msg)
l1s.pm.range.arfcn_start, l1s.pm.range.arfcn_end);
break;
}
-
+ l1s_reset_hw(); /* must reset, otherwise measurement results are delayed */
l1s_pm_test(1, l1s.pm.range.arfcn_next);
}
@@ -520,8 +532,10 @@ static void l1ctl_rx_neigh_pm_req(struct msgb *msg)
/* now reset pointer and fill list */
l1s.neigh_pm.pos = 0;
l1s.neigh_pm.running = 0;
- for (i = 0; i < pm_req->n; i++)
+ for (i = 0; i < pm_req->n; i++) {
l1s.neigh_pm.band_arfcn[i] = ntohs(pm_req->band_arfcn[i]);
+ l1s.neigh_pm.tn[i] = pm_req->tn[i];
+ }
printf("L1CTL_NEIGH_PM_REQ new list with %u entries\n", pm_req->n);
l1s.neigh_pm.n = pm_req->n; /* atomic */
@@ -552,10 +566,49 @@ static void l1ctl_rx_traffic_req(struct msgb *msg)
l1a_txq_msgb_enq(&l1s.tx_queue[L1S_CHAN_TRAFFIC], msg);
}
+static void l1ctl_sim_req(struct msgb *msg)
+{
+ uint16_t len = msg->len - sizeof(struct l1ctl_hdr);
+ uint8_t *data = msg->data + sizeof(struct l1ctl_hdr);
+
+#if 1 /* for debugging only */
+ {
+ int i;
+ printf("SIM Request (%u): ", len);
+ for (i = 0; i < len; i++)
+ printf("%02x ", data[i]);
+ puts("\n");
+ }
+#endif
+
+ sim_apdu(len, data);
+}
+
+static struct llist_head l23_rx_queue = LLIST_HEAD_INIT(l23_rx_queue);
+
/* callback from SERCOMM when L2 sends a message to L1 */
-static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
+void l1a_l23_rx(uint8_t dlci, struct msgb *msg)
{
- struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data;
+ unsigned long flags;
+
+ local_firq_save(flags);
+ msgb_enqueue(&l23_rx_queue, msg);
+ local_irq_restore(flags);
+}
+
+void l1a_l23_handler(void)
+{
+ struct msgb *msg;
+ struct l1ctl_hdr *l1h;
+ unsigned long flags;
+
+ local_firq_save(flags);
+ msg = msgb_dequeue(&l23_rx_queue);
+ local_irq_restore(flags);
+ if (!msg)
+ return;
+
+ l1h = (struct l1ctl_hdr *) msg->data;
#if 0
{
@@ -619,6 +672,9 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
l1ctl_rx_traffic_req(msg);
/* we have to keep the msgb, not free it! */
goto exit_nofree;
+ case L1CTL_SIM_REQ:
+ l1ctl_sim_req(msg);
+ break;
}
exit_msgbfree:
@@ -629,5 +685,6 @@ exit_nofree:
void l1a_l23api_init(void)
{
- sercomm_register_rx_cb(SC_DLCI_L1A_L23, l1a_l23_rx_cb);
+ sercomm_register_rx_cb(SC_DLCI_L1A_L23, l1a_l23_rx);
}
+
diff --git a/Src/osmolib/src/target/firmware/layer1/mframe_sched.c b/Src/osmolib/src/target/firmware/layer1/mframe_sched.c
index 6281c3d..2367d42 100644
--- a/Src/osmolib/src/target/firmware/layer1/mframe_sched.c
+++ b/Src/osmolib/src/target/firmware/layer1/mframe_sched.c
@@ -200,7 +200,11 @@ static const struct mframe_sched_item mf_sdcch8_7[] = {
/* Measurement for MF 51 */
static const struct mframe_sched_item mf_neigh_pm51[] = {
- { .sched_set = NEIGH_PM , .modulo = 51, .frame_nr = 50 },
+ { .sched_set = NEIGH_PM , .modulo = 51, .frame_nr = 0 },
+ { .sched_set = NEIGH_PM , .modulo = 51, .frame_nr = 10 },
+ { .sched_set = NEIGH_PM , .modulo = 51, .frame_nr = 20 },
+ { .sched_set = NEIGH_PM , .modulo = 51, .frame_nr = 30 },
+ { .sched_set = NEIGH_PM , .modulo = 51, .frame_nr = 40 },
{ .sched_set = NULL }
};
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_fbsb.c b/Src/osmolib/src/target/firmware/layer1/prim_fbsb.c
index 7affd75..e849240 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_fbsb.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_fbsb.c
@@ -30,6 +30,7 @@
#include <debug.h>
#include <memory.h>
#include <byteorder.h>
+#include <rffe.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/core/msgb.h>
#include <calypso/dsp_api.h>
@@ -47,6 +48,7 @@
#include <layer1/mframe_sched.h>
#include <layer1/tpu_window.h>
#include <layer1/l23_api.h>
+#include <layer1/agc.h>
#include <l1ctl_proto.h>
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_freq.c b/Src/osmolib/src/target/firmware/layer1/prim_freq.c
index 88bc453..ca6dc9e 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_freq.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_freq.c
@@ -45,6 +45,7 @@
#include <layer1/tdma_sched.h>
#include <layer1/tpu_window.h>
#include <layer1/l23_api.h>
+#include <layer1/sched_gsmtime.h>
#include <l1ctl_proto.h>
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_pm.c b/Src/osmolib/src/target/firmware/layer1/prim_pm.c
index c2d85ac..1630600 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_pm.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_pm.c
@@ -118,10 +118,11 @@ static int l1s_pm_resp(uint8_t num_meas, __unused uint8_t p2,
pmr->pm[1] = 0;
if (l1s.pm.mode == 1) {
- if (l1s.pm.range.arfcn_next <= l1s.pm.range.arfcn_end) {
+ if (l1s.pm.range.arfcn_next != l1s.pm.range.arfcn_end) {
/* schedule PM for next ARFCN in range */
+ l1s.pm.range.arfcn_next =
+ (l1s.pm.range.arfcn_next+1) & 0xfbff;
l1s_pm_test(1, l1s.pm.range.arfcn_next);
- l1s.pm.range.arfcn_next++;
} else {
/* we have finished, flush the msgb to L2 */
struct l1ctl_hdr *l1h = l1s.pm.msg->l1h;
@@ -174,7 +175,8 @@ static int l1s_neigh_pm_cmd(uint8_t num_meas,
* num_meas > 1 */
/* do measurement dummy, in case l1s.neigh_pm.n == 0 */
l1s_rx_win_ctrl((l1s.neigh_pm.n) ?
- l1s.neigh_pm.band_arfcn[l1s.neigh_pm.pos] : 0, L1_RXWIN_PW, 0);
+ l1s.neigh_pm.band_arfcn[l1s.neigh_pm.pos] : 0,
+ L1_RXWIN_PW, l1s.neigh_pm.tn[l1s.neigh_pm.pos]);
/* restore last gain */
rffe_set_gain(last_gain);
@@ -217,6 +219,7 @@ static int l1s_neigh_pm_resp(__unused uint8_t p1, __unused uint8_t p2,
mi = (struct l1ctl_neigh_pm_ind *)
msgb_put(msg, sizeof(*mi));
mi->band_arfcn = htons(l1s.neigh_pm.band_arfcn[i]);
+ mi->tn = l1s.neigh_pm.tn[i];
mi->pm[0] = l1s.neigh_pm.level[i];
mi->pm[1] = 0;
}
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_rach.c b/Src/osmolib/src/target/firmware/layer1/prim_rach.c
index 47f7424..27e89ab 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_rach.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_rach.c
@@ -46,6 +46,7 @@
#include <layer1/tdma_sched.h>
#include <layer1/tpu_window.h>
#include <layer1/l23_api.h>
+#include <layer1/sched_gsmtime.h>
#include <l1ctl_proto.h>
@@ -73,7 +74,7 @@ static int l1s_tx_rach_cmd(__unused uint8_t p1, __unused uint8_t p2, __unused ui
dsp_api.db_w->d_task_ra = RACH_DSP_TASK;
- l1s_tx_win_ctrl(l1s.serving_cell.arfcn, L1_TXWIN_AB, 0, 3);
+ l1s_tx_win_ctrl(l1s.serving_cell.arfcn | ARFCN_UPLINK, L1_TXWIN_AB, 0, 3);
return 0;
}
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_rx_nb.c b/Src/osmolib/src/target/firmware/layer1/prim_rx_nb.c
index 7eb4548..ade23a0 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_rx_nb.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_rx_nb.c
@@ -29,6 +29,7 @@
#include <debug.h>
#include <memory.h>
#include <byteorder.h>
+#include <rffe.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/core/msgb.h>
#include <calypso/dsp_api.h>
@@ -48,6 +49,7 @@
#include <layer1/l23_api.h>
#include <layer1/rfch.h>
#include <layer1/prim.h>
+#include <layer1/agc.h>
#include <l1ctl_proto.h>
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_tch.c b/Src/osmolib/src/target/firmware/layer1/prim_tch.c
index 96858fb..292ca10 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_tch.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_tch.c
@@ -479,7 +479,7 @@ skip_tx_traffic:
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
dsp_load_tx_task(TCHT_DSP_TASK, 0, tsc); /* burst_id unused for TCH */
- l1s_tx_win_ctrl(arfcn, L1_TXWIN_NB, 0, 3);
+ l1s_tx_win_ctrl(arfcn | ARFCN_UPLINK, L1_TXWIN_NB, 0, 3);
return 0;
}
@@ -738,7 +738,7 @@ static int l1s_tch_a_cmd(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3)
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
dsp_load_tx_task(TCHA_DSP_TASK, 0, tsc); /* burst_id unused for TCHA */
- l1s_tx_win_ctrl(arfcn, L1_TXWIN_NB, 0, 3);
+ l1s_tx_win_ctrl(arfcn, L1_TXWIN_NB | ARFCN_UPLINK, 0, 3);
return 0;
}
diff --git a/Src/osmolib/src/target/firmware/layer1/prim_tx_nb.c b/Src/osmolib/src/target/firmware/layer1/prim_tx_nb.c
index 3038178..df13c75 100644
--- a/Src/osmolib/src/target/firmware/layer1/prim_tx_nb.c
+++ b/Src/osmolib/src/target/firmware/layer1/prim_tx_nb.c
@@ -123,7 +123,7 @@ static int l1s_tx_cmd(uint8_t p1, uint8_t burst_id, uint16_t p3)
dsp_load_tx_task(DUL_DSP_TASK, burst_id, tsc);
- l1s_tx_win_ctrl(arfcn, L1_TXWIN_NB, 0, 3);
+ l1s_tx_win_ctrl(arfcn | ARFCN_UPLINK, L1_TXWIN_NB, 0, 3);
return 0;
}
diff --git a/Src/osmolib/src/target/firmware/layer1/tpu_window.c b/Src/osmolib/src/target/firmware/layer1/tpu_window.c
index 2fdb048..f4e76c1 100644
--- a/Src/osmolib/src/target/firmware/layer1/tpu_window.c
+++ b/Src/osmolib/src/target/firmware/layer1/tpu_window.c
@@ -33,6 +33,7 @@
#include <layer1/sync.h>
#include <layer1/tpu_window.h>
+#include <layer1/rfch.h>
/* all units in GSM quarter-bits (923.1ns) */
#define L1_TDMA_LENGTH_Q 5000
diff --git a/Src/osmolib/src/target/firmware/rf/mt6139.c b/Src/osmolib/src/target/firmware/rf/mt6139.c
index a9a6d32..d48e652 100644
--- a/Src/osmolib/src/target/firmware/rf/mt6139.c
+++ b/Src/osmolib/src/target/firmware/rf/mt6139.c
@@ -39,13 +39,13 @@ static void mt6139_compute_pll(uint32_t f_vco_100khz,
/* To compute Nint, we assume Nfrac is zero */
*nint = (fvco_100khz / (10 * 2 * 26)) - (0 / 130);
- if (nint > 127)
+ if (*nint > 127)
printf("VCO Frequency %u kHz is out of spec\n", f_vco_100khz);
/* Compute Nfract using the pre-computed Nint */
/* Nfrac = ( (Fvco/2*26) - Nint) * 130 */
/* Nfrac = ( (Fvco*130)/(2*26) - (Nint * 130) */
- *nfrac = (f_vco_100khz*130)/(52*10) - (nint * 130);
+ *nfrac = (f_vco_100khz*130)/(52*10) - (*nint * 130);
}
/* Set ARFCN. Takes 2 reg_write, i.e. 8 TPU instructions */
diff --git a/Src/osmolib/src/target/firmware/rf/trf6151.c b/Src/osmolib/src/target/firmware/rf/trf6151.c
index 5360402..96210fc 100644
--- a/Src/osmolib/src/target/firmware/rf/trf6151.c
+++ b/Src/osmolib/src/target/firmware/rf/trf6151.c
@@ -428,12 +428,16 @@ static void trf6151_band_select(enum trf6151_gsm_band band)
}
/* Set ARFCN. Takes 2 reg_write, i.e. 8 TPU instructions */
-void trf6151_set_arfcn(uint16_t arfcn, int uplink)
+void trf6151_set_arfcn(uint16_t arfcn, int tx)
{
uint32_t freq_khz;
uint16_t pll_config;
+ int uplink;
enum trf6151_gsm_band pll_band;
+ uplink = !!(arfcn & ARFCN_UPLINK);
+ arfcn != ~ARFCN_UPLINK;
+
switch (gsm_arfcn2band(arfcn)) {
case GSM_BAND_850:
case GSM_BAND_900:
@@ -452,7 +456,7 @@ void trf6151_set_arfcn(uint16_t arfcn, int uplink)
freq_khz = gsm_arfcn2freq10(arfcn, uplink) * 100;
printd("ARFCN %u -> %u kHz\n", arfcn, freq_khz);
- if (uplink == 0)
+ if (!tx)
trf6151_pll_rx(freq_khz, &pll_config, &pll_band);
else
trf6151_pll_tx(freq_khz, &pll_config, &pll_band);
@@ -512,7 +516,7 @@ uint8_t trf6151_get_gain(void)
void trf6151_test(uint16_t arfcn)
{
- /* Select ARFCN 871 downlink */
+ /* Select ARFCN downlink */
trf6151_set_arfcn(arfcn, 0);
trf6151_set_mode(TRF6151_RX);
@@ -532,7 +536,7 @@ void trf6151_test(uint16_t arfcn)
void trf6151_tx_test(uint16_t arfcn)
{
/* Select ARFCN uplink */
- trf6151_set_arfcn(arfcn, 1);
+ trf6151_set_arfcn(arfcn | ARFCN_UPLINK, 1);
trf6151_set_mode(TRF6151_TX);
tpu_enq_wait(TRF6151_RX_PLL_DELAY);
diff --git a/Src/osmolib/src/target_dsp/calypso/bin2cfile.py b/Src/osmolib/src/target_dsp/calypso/bin2cfile.py
index 9456a6a..9456a6a 100644..100755
--- a/Src/osmolib/src/target_dsp/calypso/bin2cfile.py
+++ b/Src/osmolib/src/target_dsp/calypso/bin2cfile.py
diff --git a/Src/osmolib/src/target_dsp/calypso/dump2coff.py b/Src/osmolib/src/target_dsp/calypso/dump2coff.py
index 67a49e8..67a49e8 100644..100755
--- a/Src/osmolib/src/target_dsp/calypso/dump2coff.py
+++ b/Src/osmolib/src/target_dsp/calypso/dump2coff.py
diff --git a/Tex/Content/GSM.tex b/Tex/Content/GSM.tex
index 0387d21..e05d113 100644
--- a/Tex/Content/GSM.tex
+++ b/Tex/Content/GSM.tex
@@ -509,7 +509,7 @@ Therefore cells with a radius above 15 km are seldom seen.
\begin{figure}
\centering
- \subfigure[Stantard configuration.]{\centering\includegraphics{../Images/standart_config}}
+ \subfigure[Stantard configuration.]{\centering\includegraphics{../Images/Standart_config}}
\subfigure[Umbrella cell configuration.]{\centering\hspace{1cm}\includegraphics{../Images/Umbrella}\hspace{1cm}}
\subfigure[Sectorised configuration.]{\centering\includegraphics{../Images/Sectorised}}
\caption{Common base station configurations. Compiled from \cite{protocols1999}.}
@@ -917,13 +917,13 @@ Four possible ways of luring a \gls{ms} to the \gls{imsi}-catcher will now be ex
Three were presented by Wehrle for the 'Open Source IMSI-catcher' project \cite{dennis} and one by Federrath \cite{mueller}.
The attacks differ on whether the \gls{ms} already is in normal cell selection mode or not, \ie it is connected to another \gls{bts}.
-\paragraph{\gls{ms} is in normal cell selection mode:}
+\paragraph{MS is in normal cell selection mode:}
The \gls{imsi}-catcher has to emulate a cell configuration of the provider the target \gls{ms} is looking for broadcasting at any frequency.
If the \gls{ms} stumbles upon the frequency it will connect.
This is no method with 100\% accuracy however chances can be raised by broadcasting with higher power.
Some \gls{imsi}-catchers even broadcast at a higher power than it would be allowed for normal \gls{bts} \cite{imsi_wiki} to make certain to be the strongest base station available to the \gls{ms}.
-\paragraph{\gls{ms} is already connected to a network:}
+\paragraph{MS is already connected to a network:}
If this is the case then the connection to the current cell needs to be broken.
It can be achieved either by jamming the frequency band of the cell the \gls{ms} is connected to thus forcing the \gls{ms} into cell selection or by getting the \gls{ms} to switch the cell to the catcher's.
This can be done the following way.
diff --git a/Tex/Images/icons/100baset hub.jpg b/Tex/Images/icons/100baset hub.jpg
new file mode 100644
index 0000000..925d5f6
--- /dev/null
+++ b/Tex/Images/icons/100baset hub.jpg
Binary files differ
diff --git a/Tex/Images/icons/10700.jpg b/Tex/Images/icons/10700.jpg
new file mode 100644
index 0000000..50bca91
--- /dev/null
+++ b/Tex/Images/icons/10700.jpg
Binary files differ
diff --git a/Tex/Images/icons/10GE_FCoE.jpg b/Tex/Images/icons/10GE_FCoE.jpg
new file mode 100644
index 0000000..8afd6ad
--- /dev/null
+++ b/Tex/Images/icons/10GE_FCoE.jpg
Binary files differ
diff --git a/Tex/Images/icons/15200.jpg b/Tex/Images/icons/15200.jpg
new file mode 100644
index 0000000..4702a12
--- /dev/null
+++ b/Tex/Images/icons/15200.jpg
Binary files differ
diff --git a/Tex/Images/icons/3174 cluster contoller .jpg b/Tex/Images/icons/3174 cluster contoller .jpg
new file mode 100644
index 0000000..e4a3deb
--- /dev/null
+++ b/Tex/Images/icons/3174 cluster contoller .jpg
Binary files differ
diff --git a/Tex/Images/icons/3200 mobile access router.jpg b/Tex/Images/icons/3200 mobile access router.jpg
new file mode 100644
index 0000000..088ff15
--- /dev/null
+++ b/Tex/Images/icons/3200 mobile access router.jpg
Binary files differ
diff --git a/Tex/Images/icons/3x74 cluster controller.jpg b/Tex/Images/icons/3x74 cluster controller.jpg
new file mode 100644
index 0000000..6bc473b
--- /dev/null
+++ b/Tex/Images/icons/3x74 cluster controller.jpg
Binary files differ
diff --git a/Tex/Images/icons/6700.jpg b/Tex/Images/icons/6700.jpg
new file mode 100644
index 0000000..03338b5
--- /dev/null
+++ b/Tex/Images/icons/6700.jpg
Binary files differ
diff --git a/Tex/Images/icons/7500ars(7513).jpg b/Tex/Images/icons/7500ars(7513).jpg
new file mode 100644
index 0000000..579ed4a
--- /dev/null
+++ b/Tex/Images/icons/7500ars(7513).jpg
Binary files differ
diff --git a/Tex/Images/icons/ACS.jpg b/Tex/Images/icons/ACS.jpg
new file mode 100644
index 0000000..eedce32
--- /dev/null
+++ b/Tex/Images/icons/ACS.jpg
Binary files differ
diff --git a/Tex/Images/icons/ASR 1000 Series.jpg b/Tex/Images/icons/ASR 1000 Series.jpg
new file mode 100644
index 0000000..bdbab4f
--- /dev/null
+++ b/Tex/Images/icons/ASR 1000 Series.jpg
Binary files differ
diff --git a/Tex/Images/icons/AXP.jpg b/Tex/Images/icons/AXP.jpg
new file mode 100644
index 0000000..b74b625
--- /dev/null
+++ b/Tex/Images/icons/AXP.jpg
Binary files differ
diff --git a/Tex/Images/icons/CUBE.jpg b/Tex/Images/icons/CUBE.jpg
new file mode 100644
index 0000000..3e4110b
--- /dev/null
+++ b/Tex/Images/icons/CUBE.jpg
Binary files differ
diff --git a/Tex/Images/icons/Cisco telepresence manager.jpg b/Tex/Images/icons/Cisco telepresence manager.jpg
new file mode 100644
index 0000000..666c99a
--- /dev/null
+++ b/Tex/Images/icons/Cisco telepresence manager.jpg
Binary files differ
diff --git a/Tex/Images/icons/Clock.jpg b/Tex/Images/icons/Clock.jpg
new file mode 100644
index 0000000..7c5de66
--- /dev/null
+++ b/Tex/Images/icons/Clock.jpg
Binary files differ
diff --git a/Tex/Images/icons/Content Acquirer.jpg b/Tex/Images/icons/Content Acquirer.jpg
new file mode 100644
index 0000000..a26f021
--- /dev/null
+++ b/Tex/Images/icons/Content Acquirer.jpg
Binary files differ
diff --git a/Tex/Images/icons/Ground terminal.jpg b/Tex/Images/icons/Ground terminal.jpg
new file mode 100644
index 0000000..fd928c5
--- /dev/null
+++ b/Tex/Images/icons/Ground terminal.jpg
Binary files differ
diff --git a/Tex/Images/icons/MSE.jpg b/Tex/Images/icons/MSE.jpg
new file mode 100644
index 0000000..20fe72b
--- /dev/null
+++ b/Tex/Images/icons/MSE.jpg
Binary files differ
diff --git a/Tex/Images/icons/MXE.jpg b/Tex/Images/icons/MXE.jpg
new file mode 100644
index 0000000..b72c545
--- /dev/null
+++ b/Tex/Images/icons/MXE.jpg
Binary files differ
diff --git a/Tex/Images/icons/Mediator.jpg b/Tex/Images/icons/Mediator.jpg
new file mode 100644
index 0000000..f22087d
--- /dev/null
+++ b/Tex/Images/icons/Mediator.jpg
Binary files differ
diff --git a/Tex/Images/icons/NCE router.jpg b/Tex/Images/icons/NCE router.jpg
new file mode 100644
index 0000000..3ba70ac
--- /dev/null
+++ b/Tex/Images/icons/NCE router.jpg
Binary files differ
diff --git a/Tex/Images/icons/NCE.jpg b/Tex/Images/icons/NCE.jpg
new file mode 100644
index 0000000..11eb371
--- /dev/null
+++ b/Tex/Images/icons/NCE.jpg
Binary files differ
diff --git a/Tex/Images/icons/Network security.jpg b/Tex/Images/icons/Network security.jpg
new file mode 100644
index 0000000..7300e29
--- /dev/null
+++ b/Tex/Images/icons/Network security.jpg
Binary files differ
diff --git a/Tex/Images/icons/Nexus 1000.jpg b/Tex/Images/icons/Nexus 1000.jpg
new file mode 100644
index 0000000..530c7cb
--- /dev/null
+++ b/Tex/Images/icons/Nexus 1000.jpg
Binary files differ
diff --git a/Tex/Images/icons/Nexus 2000.jpg b/Tex/Images/icons/Nexus 2000.jpg
new file mode 100644
index 0000000..e1992b3
--- /dev/null
+++ b/Tex/Images/icons/Nexus 2000.jpg
Binary files differ
diff --git a/Tex/Images/icons/Nexus 5000.jpg b/Tex/Images/icons/Nexus 5000.jpg
new file mode 100644
index 0000000..3df76d8
--- /dev/null
+++ b/Tex/Images/icons/Nexus 5000.jpg
Binary files differ
diff --git a/Tex/Images/icons/Nexus 7000.jpg b/Tex/Images/icons/Nexus 7000.jpg
new file mode 100644
index 0000000..a346c37
--- /dev/null
+++ b/Tex/Images/icons/Nexus 7000.jpg
Binary files differ
diff --git a/Tex/Images/icons/RF modem.jpg b/Tex/Images/icons/RF modem.jpg
new file mode 100644
index 0000000..62489d2
--- /dev/null
+++ b/Tex/Images/icons/RF modem.jpg
Binary files differ
diff --git a/Tex/Images/icons/Service Module.jpg b/Tex/Images/icons/Service Module.jpg
new file mode 100644
index 0000000..1e2d1fb
--- /dev/null
+++ b/Tex/Images/icons/Service Module.jpg
Binary files differ
diff --git a/Tex/Images/icons/Service Router.jpg b/Tex/Images/icons/Service Router.jpg
new file mode 100644
index 0000000..a8190ee
--- /dev/null
+++ b/Tex/Images/icons/Service Router.jpg
Binary files differ
diff --git a/Tex/Images/icons/Services.jpg b/Tex/Images/icons/Services.jpg
new file mode 100644
index 0000000..799ee02
--- /dev/null
+++ b/Tex/Images/icons/Services.jpg
Binary files differ
diff --git a/Tex/Images/icons/Set top box.jpg b/Tex/Images/icons/Set top box.jpg
new file mode 100644
index 0000000..2ab70e9
--- /dev/null
+++ b/Tex/Images/icons/Set top box.jpg
Binary files differ
diff --git a/Tex/Images/icons/Space router.jpg b/Tex/Images/icons/Space router.jpg
new file mode 100644
index 0000000..9977d46
--- /dev/null
+++ b/Tex/Images/icons/Space router.jpg
Binary files differ
diff --git a/Tex/Images/icons/TP MCU.jpg b/Tex/Images/icons/TP MCU.jpg
new file mode 100644
index 0000000..4e36735
--- /dev/null
+++ b/Tex/Images/icons/TP MCU.jpg
Binary files differ
diff --git a/Tex/Images/icons/VSS.jpg b/Tex/Images/icons/VSS.jpg
new file mode 100644
index 0000000..2056437
--- /dev/null
+++ b/Tex/Images/icons/VSS.jpg
Binary files differ
diff --git a/Tex/Images/icons/accesspoint.jpg b/Tex/Images/icons/accesspoint.jpg
new file mode 100644
index 0000000..411658d
--- /dev/null
+++ b/Tex/Images/icons/accesspoint.jpg
Binary files differ
diff --git a/Tex/Images/icons/ace.jpg b/Tex/Images/icons/ace.jpg
new file mode 100644
index 0000000..a26a6e5
--- /dev/null
+++ b/Tex/Images/icons/ace.jpg
Binary files differ
diff --git a/Tex/Images/icons/adm.jpg b/Tex/Images/icons/adm.jpg
new file mode 100644
index 0000000..645624e
--- /dev/null
+++ b/Tex/Images/icons/adm.jpg
Binary files differ
diff --git a/Tex/Images/icons/androgynous person.jpg b/Tex/Images/icons/androgynous person.jpg
new file mode 100644
index 0000000..13f65bc
--- /dev/null
+++ b/Tex/Images/icons/androgynous person.jpg
Binary files differ
diff --git a/Tex/Images/icons/antenna.jpg b/Tex/Images/icons/antenna.jpg
new file mode 100644
index 0000000..eab091a
--- /dev/null
+++ b/Tex/Images/icons/antenna.jpg
Binary files differ
diff --git a/Tex/Images/icons/arrows for pointing.jpg b/Tex/Images/icons/arrows for pointing.jpg
new file mode 100644
index 0000000..882fee5
--- /dev/null
+++ b/Tex/Images/icons/arrows for pointing.jpg
Binary files differ
diff --git a/Tex/Images/icons/arrows motion.jpg b/Tex/Images/icons/arrows motion.jpg
new file mode 100644
index 0000000..1cb4683
--- /dev/null
+++ b/Tex/Images/icons/arrows motion.jpg
Binary files differ
diff --git a/Tex/Images/icons/arrows-other.jpg b/Tex/Images/icons/arrows-other.jpg
new file mode 100644
index 0000000..1a41ffb
--- /dev/null
+++ b/Tex/Images/icons/arrows-other.jpg
Binary files differ
diff --git a/Tex/Images/icons/asic processor.jpg b/Tex/Images/icons/asic processor.jpg
new file mode 100644
index 0000000..d6b8813
--- /dev/null
+++ b/Tex/Images/icons/asic processor.jpg
Binary files differ
diff --git a/Tex/Images/icons/ata.jpg b/Tex/Images/icons/ata.jpg
new file mode 100644
index 0000000..dac9252
--- /dev/null
+++ b/Tex/Images/icons/ata.jpg
Binary files differ
diff --git a/Tex/Images/icons/atm 3800.jpg b/Tex/Images/icons/atm 3800.jpg
new file mode 100644
index 0000000..10d450c
--- /dev/null
+++ b/Tex/Images/icons/atm 3800.jpg
Binary files differ
diff --git a/Tex/Images/icons/atm router.jpg b/Tex/Images/icons/atm router.jpg
new file mode 100644
index 0000000..267d166
--- /dev/null
+++ b/Tex/Images/icons/atm router.jpg
Binary files differ
diff --git a/Tex/Images/icons/atm switch.jpg b/Tex/Images/icons/atm switch.jpg
new file mode 100644
index 0000000..3b88361
--- /dev/null
+++ b/Tex/Images/icons/atm switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/atm tag sw rtr.jpg b/Tex/Images/icons/atm tag sw rtr.jpg
new file mode 100644
index 0000000..2abe70e
--- /dev/null
+++ b/Tex/Images/icons/atm tag sw rtr.jpg
Binary files differ
diff --git a/Tex/Images/icons/atmfast gb ethsw.jpg b/Tex/Images/icons/atmfast gb ethsw.jpg
new file mode 100644
index 0000000..f336d59
--- /dev/null
+++ b/Tex/Images/icons/atmfast gb ethsw.jpg
Binary files differ
diff --git a/Tex/Images/icons/avs.jpg b/Tex/Images/icons/avs.jpg
new file mode 100644
index 0000000..5276131
--- /dev/null
+++ b/Tex/Images/icons/avs.jpg
Binary files differ
diff --git a/Tex/Images/icons/bbfw media.jpg b/Tex/Images/icons/bbfw media.jpg
new file mode 100644
index 0000000..385aa34
--- /dev/null
+++ b/Tex/Images/icons/bbfw media.jpg
Binary files differ
diff --git a/Tex/Images/icons/bbfw.jpg b/Tex/Images/icons/bbfw.jpg
new file mode 100644
index 0000000..72f2699
--- /dev/null
+++ b/Tex/Images/icons/bbfw.jpg
Binary files differ
diff --git a/Tex/Images/icons/bbs.jpg b/Tex/Images/icons/bbs.jpg
new file mode 100644
index 0000000..82a5e5a
--- /dev/null
+++ b/Tex/Images/icons/bbs.jpg
Binary files differ
diff --git a/Tex/Images/icons/bbsm.jpg b/Tex/Images/icons/bbsm.jpg
new file mode 100644
index 0000000..9316f62
--- /dev/null
+++ b/Tex/Images/icons/bbsm.jpg
Binary files differ
diff --git a/Tex/Images/icons/brackets.jpg b/Tex/Images/icons/brackets.jpg
new file mode 100644
index 0000000..a174346
--- /dev/null
+++ b/Tex/Images/icons/brackets.jpg
Binary files differ
diff --git a/Tex/Images/icons/branch office.jpg b/Tex/Images/icons/branch office.jpg
new file mode 100644
index 0000000..4121845
--- /dev/null
+++ b/Tex/Images/icons/branch office.jpg
Binary files differ
diff --git a/Tex/Images/icons/breakout box.jpg b/Tex/Images/icons/breakout box.jpg
new file mode 100644
index 0000000..e80b6d1
--- /dev/null
+++ b/Tex/Images/icons/breakout box.jpg
Binary files differ
diff --git a/Tex/Images/icons/bridge.jpg b/Tex/Images/icons/bridge.jpg
new file mode 100644
index 0000000..a945c05
--- /dev/null
+++ b/Tex/Images/icons/bridge.jpg
Binary files differ
diff --git a/Tex/Images/icons/broadband router d.jpg b/Tex/Images/icons/broadband router d.jpg
new file mode 100644
index 0000000..5ebae74
--- /dev/null
+++ b/Tex/Images/icons/broadband router d.jpg
Binary files differ
diff --git a/Tex/Images/icons/bts10200.jpg b/Tex/Images/icons/bts10200.jpg
new file mode 100644
index 0000000..0411772
--- /dev/null
+++ b/Tex/Images/icons/bts10200.jpg
Binary files differ
diff --git a/Tex/Images/icons/cable modem.jpg b/Tex/Images/icons/cable modem.jpg
new file mode 100644
index 0000000..cdeabb0
--- /dev/null
+++ b/Tex/Images/icons/cable modem.jpg
Binary files differ
diff --git a/Tex/Images/icons/cache director.jpg b/Tex/Images/icons/cache director.jpg
new file mode 100644
index 0000000..25f77a6
--- /dev/null
+++ b/Tex/Images/icons/cache director.jpg
Binary files differ
diff --git a/Tex/Images/icons/callmanager.jpg b/Tex/Images/icons/callmanager.jpg
new file mode 100644
index 0000000..1253598
--- /dev/null
+++ b/Tex/Images/icons/callmanager.jpg
Binary files differ
diff --git a/Tex/Images/icons/car.jpg b/Tex/Images/icons/car.jpg
new file mode 100644
index 0000000..d31607b
--- /dev/null
+++ b/Tex/Images/icons/car.jpg
Binary files differ
diff --git a/Tex/Images/icons/carrier routing system.jpg b/Tex/Images/icons/carrier routing system.jpg
new file mode 100644
index 0000000..c45ac4d
--- /dev/null
+++ b/Tex/Images/icons/carrier routing system.jpg
Binary files differ
diff --git a/Tex/Images/icons/catalyst access gateway.jpg b/Tex/Images/icons/catalyst access gateway.jpg
new file mode 100644
index 0000000..4621f4b
--- /dev/null
+++ b/Tex/Images/icons/catalyst access gateway.jpg
Binary files differ
diff --git a/Tex/Images/icons/cddi-fddi.jpg b/Tex/Images/icons/cddi-fddi.jpg
new file mode 100644
index 0000000..3873899
--- /dev/null
+++ b/Tex/Images/icons/cddi-fddi.jpg
Binary files differ
diff --git a/Tex/Images/icons/cdm.jpg b/Tex/Images/icons/cdm.jpg
new file mode 100644
index 0000000..7444060
--- /dev/null
+++ b/Tex/Images/icons/cdm.jpg
Binary files differ
diff --git a/Tex/Images/icons/cellular phone.jpg b/Tex/Images/icons/cellular phone.jpg
new file mode 100644
index 0000000..0f8c948
--- /dev/null
+++ b/Tex/Images/icons/cellular phone.jpg
Binary files differ
diff --git a/Tex/Images/icons/centri firewall.jpg b/Tex/Images/icons/centri firewall.jpg
new file mode 100644
index 0000000..2dd7a41
--- /dev/null
+++ b/Tex/Images/icons/centri firewall.jpg
Binary files differ
diff --git a/Tex/Images/icons/cisco 1000.jpg b/Tex/Images/icons/cisco 1000.jpg
new file mode 100644
index 0000000..ec4f498
--- /dev/null
+++ b/Tex/Images/icons/cisco 1000.jpg
Binary files differ
diff --git a/Tex/Images/icons/cisco asa 5500.jpg b/Tex/Images/icons/cisco asa 5500.jpg
new file mode 100644
index 0000000..3652ec9
--- /dev/null
+++ b/Tex/Images/icons/cisco asa 5500.jpg
Binary files differ
diff --git a/Tex/Images/icons/cisco file engine.jpg b/Tex/Images/icons/cisco file engine.jpg
new file mode 100644
index 0000000..1dd2a93
--- /dev/null
+++ b/Tex/Images/icons/cisco file engine.jpg
Binary files differ
diff --git a/Tex/Images/icons/cisco hub.jpg b/Tex/Images/icons/cisco hub.jpg
new file mode 100644
index 0000000..7c045bd
--- /dev/null
+++ b/Tex/Images/icons/cisco hub.jpg
Binary files differ
diff --git a/Tex/Images/icons/cisco unified presence server.jpg b/Tex/Images/icons/cisco unified presence server.jpg
new file mode 100644
index 0000000..803bb07
--- /dev/null
+++ b/Tex/Images/icons/cisco unified presence server.jpg
Binary files differ
diff --git a/Tex/Images/icons/cisco unityexpress.jpg b/Tex/Images/icons/cisco unityexpress.jpg
new file mode 100644
index 0000000..f7772a5
--- /dev/null
+++ b/Tex/Images/icons/cisco unityexpress.jpg
Binary files differ
diff --git a/Tex/Images/icons/ciscoca.jpg b/Tex/Images/icons/ciscoca.jpg
new file mode 100644
index 0000000..bdd03f3
--- /dev/null
+++ b/Tex/Images/icons/ciscoca.jpg
Binary files differ
diff --git a/Tex/Images/icons/ciscosecurity.jpg b/Tex/Images/icons/ciscosecurity.jpg
new file mode 100644
index 0000000..9b25b36
--- /dev/null
+++ b/Tex/Images/icons/ciscosecurity.jpg
Binary files differ
diff --git a/Tex/Images/icons/ciscoworks workstn.jpg b/Tex/Images/icons/ciscoworks workstn.jpg
new file mode 100644
index 0000000..15416b0
--- /dev/null
+++ b/Tex/Images/icons/ciscoworks workstn.jpg
Binary files differ
diff --git a/Tex/Images/icons/class 4_5 switch.jpg b/Tex/Images/icons/class 4_5 switch.jpg
new file mode 100644
index 0000000..2731d24
--- /dev/null
+++ b/Tex/Images/icons/class 4_5 switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/cloud.jpg b/Tex/Images/icons/cloud.jpg
new file mode 100644
index 0000000..cdbd1ed
--- /dev/null
+++ b/Tex/Images/icons/cloud.jpg
Binary files differ
diff --git a/Tex/Images/icons/comm server.jpg b/Tex/Images/icons/comm server.jpg
new file mode 100644
index 0000000..c3c9a6d
--- /dev/null
+++ b/Tex/Images/icons/comm server.jpg
Binary files differ
diff --git a/Tex/Images/icons/concentrator.jpg b/Tex/Images/icons/concentrator.jpg
new file mode 100644
index 0000000..7278335
--- /dev/null
+++ b/Tex/Images/icons/concentrator.jpg
Binary files differ
diff --git a/Tex/Images/icons/contact center.jpg b/Tex/Images/icons/contact center.jpg
new file mode 100644
index 0000000..450ab47
--- /dev/null
+++ b/Tex/Images/icons/contact center.jpg
Binary files differ
diff --git a/Tex/Images/icons/content engine.jpg b/Tex/Images/icons/content engine.jpg
new file mode 100644
index 0000000..3f86c6e
--- /dev/null
+++ b/Tex/Images/icons/content engine.jpg
Binary files differ
diff --git a/Tex/Images/icons/content switch 11000.jpg b/Tex/Images/icons/content switch 11000.jpg
new file mode 100644
index 0000000..d4ac208
--- /dev/null
+++ b/Tex/Images/icons/content switch 11000.jpg
Binary files differ
diff --git a/Tex/Images/icons/content switch module.jpg b/Tex/Images/icons/content switch module.jpg
new file mode 100644
index 0000000..2a8472f
--- /dev/null
+++ b/Tex/Images/icons/content switch module.jpg
Binary files differ
diff --git a/Tex/Images/icons/content switch.jpg b/Tex/Images/icons/content switch.jpg
new file mode 100644
index 0000000..8bb80c2
--- /dev/null
+++ b/Tex/Images/icons/content switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/contentservice router.jpg b/Tex/Images/icons/contentservice router.jpg
new file mode 100644
index 0000000..2bd5d91
--- /dev/null
+++ b/Tex/Images/icons/contentservice router.jpg
Binary files differ
diff --git a/Tex/Images/icons/cs-mars.jpg b/Tex/Images/icons/cs-mars.jpg
new file mode 100644
index 0000000..b64c1ef
--- /dev/null
+++ b/Tex/Images/icons/cs-mars.jpg
Binary files differ
diff --git a/Tex/Images/icons/csm-s.jpg b/Tex/Images/icons/csm-s.jpg
new file mode 100644
index 0000000..07e0e61
--- /dev/null
+++ b/Tex/Images/icons/csm-s.jpg
Binary files differ
diff --git a/Tex/Images/icons/csu dsu.jpg b/Tex/Images/icons/csu dsu.jpg
new file mode 100644
index 0000000..5ea3556
--- /dev/null
+++ b/Tex/Images/icons/csu dsu.jpg
Binary files differ
diff --git a/Tex/Images/icons/cte.jpg b/Tex/Images/icons/cte.jpg
new file mode 100644
index 0000000..e0ee2c0
--- /dev/null
+++ b/Tex/Images/icons/cte.jpg
Binary files differ
diff --git a/Tex/Images/icons/cuc.jpg b/Tex/Images/icons/cuc.jpg
new file mode 100644
index 0000000..01399c5
--- /dev/null
+++ b/Tex/Images/icons/cuc.jpg
Binary files differ
diff --git a/Tex/Images/icons/detector.jpg b/Tex/Images/icons/detector.jpg
new file mode 100644
index 0000000..02e6346
--- /dev/null
+++ b/Tex/Images/icons/detector.jpg
Binary files differ
diff --git a/Tex/Images/icons/director-class fibre channel director.jpg b/Tex/Images/icons/director-class fibre channel director.jpg
new file mode 100644
index 0000000..8dbc115
--- /dev/null
+++ b/Tex/Images/icons/director-class fibre channel director.jpg
Binary files differ
diff --git a/Tex/Images/icons/directory server.jpg b/Tex/Images/icons/directory server.jpg
new file mode 100644
index 0000000..6a492cd
--- /dev/null
+++ b/Tex/Images/icons/directory server.jpg
Binary files differ
diff --git a/Tex/Images/icons/disk subsystem.jpg b/Tex/Images/icons/disk subsystem.jpg
new file mode 100644
index 0000000..4cfca9f
--- /dev/null
+++ b/Tex/Images/icons/disk subsystem.jpg
Binary files differ
diff --git a/Tex/Images/icons/diskette.jpg b/Tex/Images/icons/diskette.jpg
new file mode 100644
index 0000000..586a856
--- /dev/null
+++ b/Tex/Images/icons/diskette.jpg
Binary files differ
diff --git a/Tex/Images/icons/distributed director.jpg b/Tex/Images/icons/distributed director.jpg
new file mode 100644
index 0000000..ead64ed
--- /dev/null
+++ b/Tex/Images/icons/distributed director.jpg
Binary files differ
diff --git a/Tex/Images/icons/dot-dot.jpg b/Tex/Images/icons/dot-dot.jpg
new file mode 100644
index 0000000..ae3fa4f
--- /dev/null
+++ b/Tex/Images/icons/dot-dot.jpg
Binary files differ
diff --git a/Tex/Images/icons/dpt.jpg b/Tex/Images/icons/dpt.jpg
new file mode 100644
index 0000000..82e1d4d
--- /dev/null
+++ b/Tex/Images/icons/dpt.jpg
Binary files differ
diff --git a/Tex/Images/icons/dslam.jpg b/Tex/Images/icons/dslam.jpg
new file mode 100644
index 0000000..4a62c4f
--- /dev/null
+++ b/Tex/Images/icons/dslam.jpg
Binary files differ
diff --git a/Tex/Images/icons/dual mode ap.jpg b/Tex/Images/icons/dual mode ap.jpg
new file mode 100644
index 0000000..5c93d25
--- /dev/null
+++ b/Tex/Images/icons/dual mode ap.jpg
Binary files differ
diff --git a/Tex/Images/icons/dwdm filter.jpg b/Tex/Images/icons/dwdm filter.jpg
new file mode 100644
index 0000000..2d6af32
--- /dev/null
+++ b/Tex/Images/icons/dwdm filter.jpg
Binary files differ
diff --git a/Tex/Images/icons/end office .jpg b/Tex/Images/icons/end office .jpg
new file mode 100644
index 0000000..e697885
--- /dev/null
+++ b/Tex/Images/icons/end office .jpg
Binary files differ
diff --git a/Tex/Images/icons/fax.jpg b/Tex/Images/icons/fax.jpg
new file mode 100644
index 0000000..4cf8967
--- /dev/null
+++ b/Tex/Images/icons/fax.jpg
Binary files differ
diff --git a/Tex/Images/icons/fc storage.jpg b/Tex/Images/icons/fc storage.jpg
new file mode 100644
index 0000000..aeea660
--- /dev/null
+++ b/Tex/Images/icons/fc storage.jpg
Binary files differ
diff --git a/Tex/Images/icons/fddi ring.jpg b/Tex/Images/icons/fddi ring.jpg
new file mode 100644
index 0000000..15e9b44
--- /dev/null
+++ b/Tex/Images/icons/fddi ring.jpg
Binary files differ
diff --git a/Tex/Images/icons/fibre channel fabric switch.jpg b/Tex/Images/icons/fibre channel fabric switch.jpg
new file mode 100644
index 0000000..bd65a02
--- /dev/null
+++ b/Tex/Images/icons/fibre channel fabric switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/file cabinet.jpg b/Tex/Images/icons/file cabinet.jpg
new file mode 100644
index 0000000..c4ab475
--- /dev/null
+++ b/Tex/Images/icons/file cabinet.jpg
Binary files differ
diff --git a/Tex/Images/icons/file server.jpg b/Tex/Images/icons/file server.jpg
new file mode 100644
index 0000000..328ab94
--- /dev/null
+++ b/Tex/Images/icons/file server.jpg
Binary files differ
diff --git a/Tex/Images/icons/firewall.jpg b/Tex/Images/icons/firewall.jpg
new file mode 100644
index 0000000..2b6f354
--- /dev/null
+++ b/Tex/Images/icons/firewall.jpg
Binary files differ
diff --git a/Tex/Images/icons/floppy disk.jpg b/Tex/Images/icons/floppy disk.jpg
new file mode 100644
index 0000000..660355f
--- /dev/null
+++ b/Tex/Images/icons/floppy disk.jpg
Binary files differ
diff --git a/Tex/Images/icons/front end processor.jpg b/Tex/Images/icons/front end processor.jpg
new file mode 100644
index 0000000..649204c
--- /dev/null
+++ b/Tex/Images/icons/front end processor.jpg
Binary files differ
diff --git a/Tex/Images/icons/fwsm.jpg b/Tex/Images/icons/fwsm.jpg
new file mode 100644
index 0000000..9cb6d27
--- /dev/null
+++ b/Tex/Images/icons/fwsm.jpg
Binary files differ
diff --git a/Tex/Images/icons/gatekeeper.jpg b/Tex/Images/icons/gatekeeper.jpg
new file mode 100644
index 0000000..56e50cb
--- /dev/null
+++ b/Tex/Images/icons/gatekeeper.jpg
Binary files differ
diff --git a/Tex/Images/icons/general applicance.jpg b/Tex/Images/icons/general applicance.jpg
new file mode 100644
index 0000000..b930d3e
--- /dev/null
+++ b/Tex/Images/icons/general applicance.jpg
Binary files differ
diff --git a/Tex/Images/icons/general processor.jpg b/Tex/Images/icons/general processor.jpg
new file mode 100644
index 0000000..97727a4
--- /dev/null
+++ b/Tex/Images/icons/general processor.jpg
Binary files differ
diff --git a/Tex/Images/icons/generic building.jpg b/Tex/Images/icons/generic building.jpg
new file mode 100644
index 0000000..9f710f2
--- /dev/null
+++ b/Tex/Images/icons/generic building.jpg
Binary files differ
diff --git a/Tex/Images/icons/generic gateway.jpg b/Tex/Images/icons/generic gateway.jpg
new file mode 100644
index 0000000..4a757a6
--- /dev/null
+++ b/Tex/Images/icons/generic gateway.jpg
Binary files differ
diff --git a/Tex/Images/icons/generic softswitch.jpg b/Tex/Images/icons/generic softswitch.jpg
new file mode 100644
index 0000000..8f01b0f
--- /dev/null
+++ b/Tex/Images/icons/generic softswitch.jpg
Binary files differ
diff --git a/Tex/Images/icons/gigabit switch router.jpg b/Tex/Images/icons/gigabit switch router.jpg
new file mode 100644
index 0000000..4b53833
--- /dev/null
+++ b/Tex/Images/icons/gigabit switch router.jpg
Binary files differ
diff --git a/Tex/Images/icons/government building.jpg b/Tex/Images/icons/government building.jpg
new file mode 100644
index 0000000..f51920d
--- /dev/null
+++ b/Tex/Images/icons/government building.jpg
Binary files differ
diff --git a/Tex/Images/icons/guard.jpg b/Tex/Images/icons/guard.jpg
new file mode 100644
index 0000000..3936c4f
--- /dev/null
+++ b/Tex/Images/icons/guard.jpg
Binary files differ
diff --git a/Tex/Images/icons/h.323.jpg b/Tex/Images/icons/h.323.jpg
new file mode 100644
index 0000000..d07134b
--- /dev/null
+++ b/Tex/Images/icons/h.323.jpg
Binary files differ
diff --git a/Tex/Images/icons/hand_cell.jpg b/Tex/Images/icons/hand_cell.jpg
new file mode 100644
index 0000000..43997c4
--- /dev/null
+++ b/Tex/Images/icons/hand_cell.jpg
Binary files differ
diff --git a/Tex/Images/icons/handheld.jpg b/Tex/Images/icons/handheld.jpg
new file mode 100644
index 0000000..29cc29c
--- /dev/null
+++ b/Tex/Images/icons/handheld.jpg
Binary files differ
diff --git a/Tex/Images/icons/hootphone.jpg b/Tex/Images/icons/hootphone.jpg
new file mode 100644
index 0000000..11bdfe2
--- /dev/null
+++ b/Tex/Images/icons/hootphone.jpg
Binary files differ
diff --git a/Tex/Images/icons/host (generic).jpg b/Tex/Images/icons/host (generic).jpg
new file mode 100644
index 0000000..9321077
--- /dev/null
+++ b/Tex/Images/icons/host (generic).jpg
Binary files differ
diff --git a/Tex/Images/icons/host.jpg b/Tex/Images/icons/host.jpg
new file mode 100644
index 0000000..53448c3
--- /dev/null
+++ b/Tex/Images/icons/host.jpg
Binary files differ
diff --git a/Tex/Images/icons/hp mini.jpg b/Tex/Images/icons/hp mini.jpg
new file mode 100644
index 0000000..3810a0b
--- /dev/null
+++ b/Tex/Images/icons/hp mini.jpg
Binary files differ
diff --git a/Tex/Images/icons/hub.jpg b/Tex/Images/icons/hub.jpg
new file mode 100644
index 0000000..71ea8fd
--- /dev/null
+++ b/Tex/Images/icons/hub.jpg
Binary files differ
diff --git a/Tex/Images/icons/iad router.jpg b/Tex/Images/icons/iad router.jpg
new file mode 100644
index 0000000..af2cc40
--- /dev/null
+++ b/Tex/Images/icons/iad router.jpg
Binary files differ
diff --git a/Tex/Images/icons/ibm maniframe.jpg b/Tex/Images/icons/ibm maniframe.jpg
new file mode 100644
index 0000000..ed9b31b
--- /dev/null
+++ b/Tex/Images/icons/ibm maniframe.jpg
Binary files differ
diff --git a/Tex/Images/icons/ibm mini (as400).jpg b/Tex/Images/icons/ibm mini (as400).jpg
new file mode 100644
index 0000000..cd74e50
--- /dev/null
+++ b/Tex/Images/icons/ibm mini (as400).jpg
Binary files differ
diff --git a/Tex/Images/icons/ibm tower.jpg b/Tex/Images/icons/ibm tower.jpg
new file mode 100644
index 0000000..6a0c82d
--- /dev/null
+++ b/Tex/Images/icons/ibm tower.jpg
Binary files differ
diff --git a/Tex/Images/icons/icm.jpg b/Tex/Images/icons/icm.jpg
new file mode 100644
index 0000000..b700bc8
--- /dev/null
+++ b/Tex/Images/icons/icm.jpg
Binary files differ
diff --git a/Tex/Images/icons/ics.jpg b/Tex/Images/icons/ics.jpg
new file mode 100644
index 0000000..66747bd
--- /dev/null
+++ b/Tex/Images/icons/ics.jpg
Binary files differ
diff --git a/Tex/Images/icons/intelliswitch stack.jpg b/Tex/Images/icons/intelliswitch stack.jpg
new file mode 100644
index 0000000..6ca6f08
--- /dev/null
+++ b/Tex/Images/icons/intelliswitch stack.jpg
Binary files differ
diff --git a/Tex/Images/icons/ios firewall.jpg b/Tex/Images/icons/ios firewall.jpg
new file mode 100644
index 0000000..706bff7
--- /dev/null
+++ b/Tex/Images/icons/ios firewall.jpg
Binary files differ
diff --git a/Tex/Images/icons/ios slb.jpg b/Tex/Images/icons/ios slb.jpg
new file mode 100644
index 0000000..5937bff
--- /dev/null
+++ b/Tex/Images/icons/ios slb.jpg
Binary files differ
diff --git a/Tex/Images/icons/ip communicator.jpg b/Tex/Images/icons/ip communicator.jpg
new file mode 100644
index 0000000..5542db0
--- /dev/null
+++ b/Tex/Images/icons/ip communicator.jpg
Binary files differ
diff --git a/Tex/Images/icons/ip dsl.jpg b/Tex/Images/icons/ip dsl.jpg
new file mode 100644
index 0000000..16c703d
--- /dev/null
+++ b/Tex/Images/icons/ip dsl.jpg
Binary files differ
diff --git a/Tex/Images/icons/ip phone.jpg b/Tex/Images/icons/ip phone.jpg
new file mode 100644
index 0000000..90dbbf8
--- /dev/null
+++ b/Tex/Images/icons/ip phone.jpg
Binary files differ
diff --git a/Tex/Images/icons/ip telephony router.jpg b/Tex/Images/icons/ip telephony router.jpg
new file mode 100644
index 0000000..8393a88
--- /dev/null
+++ b/Tex/Images/icons/ip telephony router.jpg
Binary files differ
diff --git a/Tex/Images/icons/ip.jpg b/Tex/Images/icons/ip.jpg
new file mode 100644
index 0000000..65344aa
--- /dev/null
+++ b/Tex/Images/icons/ip.jpg
Binary files differ
diff --git a/Tex/Images/icons/iptc.jpg b/Tex/Images/icons/iptc.jpg
new file mode 100644
index 0000000..98b2988
--- /dev/null
+++ b/Tex/Images/icons/iptc.jpg
Binary files differ
diff --git a/Tex/Images/icons/iptv broadcast server.jpg b/Tex/Images/icons/iptv broadcast server.jpg
new file mode 100644
index 0000000..ddc4839
--- /dev/null
+++ b/Tex/Images/icons/iptv broadcast server.jpg
Binary files differ
diff --git a/Tex/Images/icons/iptv content manager.jpg b/Tex/Images/icons/iptv content manager.jpg
new file mode 100644
index 0000000..108c9a0
--- /dev/null
+++ b/Tex/Images/icons/iptv content manager.jpg
Binary files differ
diff --git a/Tex/Images/icons/iscsi router.jpg b/Tex/Images/icons/iscsi router.jpg
new file mode 100644
index 0000000..5369677
--- /dev/null
+++ b/Tex/Images/icons/iscsi router.jpg
Binary files differ
diff --git a/Tex/Images/icons/isdn switch.jpg b/Tex/Images/icons/isdn switch.jpg
new file mode 100644
index 0000000..4835a5e
--- /dev/null
+++ b/Tex/Images/icons/isdn switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/itp.jpg b/Tex/Images/icons/itp.jpg
new file mode 100644
index 0000000..0557b63
--- /dev/null
+++ b/Tex/Images/icons/itp.jpg
Binary files differ
diff --git a/Tex/Images/icons/jbod.jpg b/Tex/Images/icons/jbod.jpg
new file mode 100644
index 0000000..21c4b63
--- /dev/null
+++ b/Tex/Images/icons/jbod.jpg
Binary files differ
diff --git a/Tex/Images/icons/key.jpg b/Tex/Images/icons/key.jpg
new file mode 100644
index 0000000..0643cdf
--- /dev/null
+++ b/Tex/Images/icons/key.jpg
Binary files differ
diff --git a/Tex/Images/icons/keys.jpg b/Tex/Images/icons/keys.jpg
new file mode 100644
index 0000000..0c4f99f
--- /dev/null
+++ b/Tex/Images/icons/keys.jpg
Binary files differ
diff --git a/Tex/Images/icons/lan2lan.jpg b/Tex/Images/icons/lan2lan.jpg
new file mode 100644
index 0000000..57a2fa5
--- /dev/null
+++ b/Tex/Images/icons/lan2lan.jpg
Binary files differ
diff --git a/Tex/Images/icons/laptop.jpg b/Tex/Images/icons/laptop.jpg
new file mode 100644
index 0000000..3d50fcd
--- /dev/null
+++ b/Tex/Images/icons/laptop.jpg
Binary files differ
diff --git a/Tex/Images/icons/layer 2 remote switch.jpg b/Tex/Images/icons/layer 2 remote switch.jpg
new file mode 100644
index 0000000..26aee58
--- /dev/null
+++ b/Tex/Images/icons/layer 2 remote switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/layer 3 switch.jpg b/Tex/Images/icons/layer 3 switch.jpg
new file mode 100644
index 0000000..7eaedcc
--- /dev/null
+++ b/Tex/Images/icons/layer 3 switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/lightweight ap.jpg b/Tex/Images/icons/lightweight ap.jpg
new file mode 100644
index 0000000..a12edea
--- /dev/null
+++ b/Tex/Images/icons/lightweight ap.jpg
Binary files differ
diff --git a/Tex/Images/icons/local director.jpg b/Tex/Images/icons/local director.jpg
new file mode 100644
index 0000000..db36a0d
--- /dev/null
+++ b/Tex/Images/icons/local director.jpg
Binary files differ
diff --git a/Tex/Images/icons/lock.jpg b/Tex/Images/icons/lock.jpg
new file mode 100644
index 0000000..01e51f2
--- /dev/null
+++ b/Tex/Images/icons/lock.jpg
Binary files differ
diff --git a/Tex/Images/icons/longreach cpe.jpg b/Tex/Images/icons/longreach cpe.jpg
new file mode 100644
index 0000000..345b1ed
--- /dev/null
+++ b/Tex/Images/icons/longreach cpe.jpg
Binary files differ
diff --git a/Tex/Images/icons/mac woman.jpg b/Tex/Images/icons/mac woman.jpg
new file mode 100644
index 0000000..cde62ee
--- /dev/null
+++ b/Tex/Images/icons/mac woman.jpg
Binary files differ
diff --git a/Tex/Images/icons/macintosh.jpg b/Tex/Images/icons/macintosh.jpg
new file mode 100644
index 0000000..bf55ead
--- /dev/null
+++ b/Tex/Images/icons/macintosh.jpg
Binary files differ
diff --git a/Tex/Images/icons/man woman.jpg b/Tex/Images/icons/man woman.jpg
new file mode 100644
index 0000000..ee7ca18
--- /dev/null
+++ b/Tex/Images/icons/man woman.jpg
Binary files differ
diff --git a/Tex/Images/icons/mas gateway.jpg b/Tex/Images/icons/mas gateway.jpg
new file mode 100644
index 0000000..064eece
--- /dev/null
+++ b/Tex/Images/icons/mas gateway.jpg
Binary files differ
diff --git a/Tex/Images/icons/mau.jpg b/Tex/Images/icons/mau.jpg
new file mode 100644
index 0000000..06737c9
--- /dev/null
+++ b/Tex/Images/icons/mau.jpg
Binary files differ
diff --git a/Tex/Images/icons/mcu.jpg b/Tex/Images/icons/mcu.jpg
new file mode 100644
index 0000000..62fc73b
--- /dev/null
+++ b/Tex/Images/icons/mcu.jpg
Binary files differ
diff --git a/Tex/Images/icons/mdu.jpg b/Tex/Images/icons/mdu.jpg
new file mode 100644
index 0000000..2f51831
--- /dev/null
+++ b/Tex/Images/icons/mdu.jpg
Binary files differ
diff --git a/Tex/Images/icons/me1100.jpg b/Tex/Images/icons/me1100.jpg
new file mode 100644
index 0000000..4e93cc3
--- /dev/null
+++ b/Tex/Images/icons/me1100.jpg
Binary files differ
diff --git a/Tex/Images/icons/meetingplace.jpg b/Tex/Images/icons/meetingplace.jpg
new file mode 100644
index 0000000..634d0b4
--- /dev/null
+++ b/Tex/Images/icons/meetingplace.jpg
Binary files differ
diff --git a/Tex/Images/icons/mesh ap.jpg b/Tex/Images/icons/mesh ap.jpg
new file mode 100644
index 0000000..8427c93
--- /dev/null
+++ b/Tex/Images/icons/mesh ap.jpg
Binary files differ
diff --git a/Tex/Images/icons/metro1500.jpg b/Tex/Images/icons/metro1500.jpg
new file mode 100644
index 0000000..36de040
--- /dev/null
+++ b/Tex/Images/icons/metro1500.jpg
Binary files differ
diff --git a/Tex/Images/icons/mgx 8000 multiservice switch.jpg b/Tex/Images/icons/mgx 8000 multiservice switch.jpg
new file mode 100644
index 0000000..42f19e2
--- /dev/null
+++ b/Tex/Images/icons/mgx 8000 multiservice switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/microphone.jpg b/Tex/Images/icons/microphone.jpg
new file mode 100644
index 0000000..f6779d1
--- /dev/null
+++ b/Tex/Images/icons/microphone.jpg
Binary files differ
diff --git a/Tex/Images/icons/microwebserver.jpg b/Tex/Images/icons/microwebserver.jpg
new file mode 100644
index 0000000..cefe5ce
--- /dev/null
+++ b/Tex/Images/icons/microwebserver.jpg
Binary files differ
diff --git a/Tex/Images/icons/mini vax.jpg b/Tex/Images/icons/mini vax.jpg
new file mode 100644
index 0000000..984ba6d
--- /dev/null
+++ b/Tex/Images/icons/mini vax.jpg
Binary files differ
diff --git a/Tex/Images/icons/mobile access ip phone.jpg b/Tex/Images/icons/mobile access ip phone.jpg
new file mode 100644
index 0000000..083418c
--- /dev/null
+++ b/Tex/Images/icons/mobile access ip phone.jpg
Binary files differ
diff --git a/Tex/Images/icons/mobile access router.jpg b/Tex/Images/icons/mobile access router.jpg
new file mode 100644
index 0000000..4842af4
--- /dev/null
+++ b/Tex/Images/icons/mobile access router.jpg
Binary files differ
diff --git a/Tex/Images/icons/modem.jpg b/Tex/Images/icons/modem.jpg
new file mode 100644
index 0000000..32dd13c
--- /dev/null
+++ b/Tex/Images/icons/modem.jpg
Binary files differ
diff --git a/Tex/Images/icons/moh server.jpg b/Tex/Images/icons/moh server.jpg
new file mode 100644
index 0000000..19fd59c
--- /dev/null
+++ b/Tex/Images/icons/moh server.jpg
Binary files differ
diff --git a/Tex/Images/icons/multi-fabric server switch.jpg b/Tex/Images/icons/multi-fabric server switch.jpg
new file mode 100644
index 0000000..1a3ee19
--- /dev/null
+++ b/Tex/Images/icons/multi-fabric server switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/multilayer remote switch.jpg b/Tex/Images/icons/multilayer remote switch.jpg
new file mode 100644
index 0000000..2e37bc1
--- /dev/null
+++ b/Tex/Images/icons/multilayer remote switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/multilayer switch.jpg b/Tex/Images/icons/multilayer switch.jpg
new file mode 100644
index 0000000..91e3a6f
--- /dev/null
+++ b/Tex/Images/icons/multilayer switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/multiswdevice.jpg b/Tex/Images/icons/multiswdevice.jpg
new file mode 100644
index 0000000..1d1a5a5
--- /dev/null
+++ b/Tex/Images/icons/multiswdevice.jpg
Binary files differ
diff --git a/Tex/Images/icons/mux.jpg b/Tex/Images/icons/mux.jpg
new file mode 100644
index 0000000..a00e235
--- /dev/null
+++ b/Tex/Images/icons/mux.jpg
Binary files differ
diff --git a/Tex/Images/icons/nac appliance.jpg b/Tex/Images/icons/nac appliance.jpg
new file mode 100644
index 0000000..34ef561
--- /dev/null
+++ b/Tex/Images/icons/nac appliance.jpg
Binary files differ
diff --git a/Tex/Images/icons/netflow router.jpg b/Tex/Images/icons/netflow router.jpg
new file mode 100644
index 0000000..8b6adc1
--- /dev/null
+++ b/Tex/Images/icons/netflow router.jpg
Binary files differ
diff --git a/Tex/Images/icons/netranger.jpg b/Tex/Images/icons/netranger.jpg
new file mode 100644
index 0000000..b4247f0
--- /dev/null
+++ b/Tex/Images/icons/netranger.jpg
Binary files differ
diff --git a/Tex/Images/icons/netsonar.jpg b/Tex/Images/icons/netsonar.jpg
new file mode 100644
index 0000000..4a36932
--- /dev/null
+++ b/Tex/Images/icons/netsonar.jpg
Binary files differ
diff --git a/Tex/Images/icons/network management.jpg b/Tex/Images/icons/network management.jpg
new file mode 100644
index 0000000..09d460c
--- /dev/null
+++ b/Tex/Images/icons/network management.jpg
Binary files differ
diff --git a/Tex/Images/icons/octel.jpg b/Tex/Images/icons/octel.jpg
new file mode 100644
index 0000000..c34aabd
--- /dev/null
+++ b/Tex/Images/icons/octel.jpg
Binary files differ
diff --git a/Tex/Images/icons/ons15500.jpg b/Tex/Images/icons/ons15500.jpg
new file mode 100644
index 0000000..6c8ad40
--- /dev/null
+++ b/Tex/Images/icons/ons15500.jpg
Binary files differ
diff --git a/Tex/Images/icons/optical amplifier.jpg b/Tex/Images/icons/optical amplifier.jpg
new file mode 100644
index 0000000..9fc38ab
--- /dev/null
+++ b/Tex/Images/icons/optical amplifier.jpg
Binary files differ
diff --git a/Tex/Images/icons/optical services router.jpg b/Tex/Images/icons/optical services router.jpg
new file mode 100644
index 0000000..a707629
--- /dev/null
+++ b/Tex/Images/icons/optical services router.jpg
Binary files differ
diff --git a/Tex/Images/icons/optical transport.jpg b/Tex/Images/icons/optical transport.jpg
new file mode 100644
index 0000000..d5a4322
--- /dev/null
+++ b/Tex/Images/icons/optical transport.jpg
Binary files differ
diff --git a/Tex/Images/icons/pad x.28.jpg b/Tex/Images/icons/pad x.28.jpg
new file mode 100644
index 0000000..18f4d11
--- /dev/null
+++ b/Tex/Images/icons/pad x.28.jpg
Binary files differ
diff --git a/Tex/Images/icons/pad.jpg b/Tex/Images/icons/pad.jpg
new file mode 100644
index 0000000..d348a44
--- /dev/null
+++ b/Tex/Images/icons/pad.jpg
Binary files differ
diff --git a/Tex/Images/icons/page icon.jpg b/Tex/Images/icons/page icon.jpg
new file mode 100644
index 0000000..f8f55ef
--- /dev/null
+++ b/Tex/Images/icons/page icon.jpg
Binary files differ
diff --git a/Tex/Images/icons/pbx switch.jpg b/Tex/Images/icons/pbx switch.jpg
new file mode 100644
index 0000000..4d808fc
--- /dev/null
+++ b/Tex/Images/icons/pbx switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/pbx.jpg b/Tex/Images/icons/pbx.jpg
new file mode 100644
index 0000000..25b2ba6
--- /dev/null
+++ b/Tex/Images/icons/pbx.jpg
Binary files differ
diff --git a/Tex/Images/icons/pc adapter card.jpg b/Tex/Images/icons/pc adapter card.jpg
new file mode 100644
index 0000000..0bcf588
--- /dev/null
+++ b/Tex/Images/icons/pc adapter card.jpg
Binary files differ
diff --git a/Tex/Images/icons/pc man.jpg b/Tex/Images/icons/pc man.jpg
new file mode 100644
index 0000000..1cc23b0
--- /dev/null
+++ b/Tex/Images/icons/pc man.jpg
Binary files differ
diff --git a/Tex/Images/icons/pc router card.jpg b/Tex/Images/icons/pc router card.jpg
new file mode 100644
index 0000000..f247b57
--- /dev/null
+++ b/Tex/Images/icons/pc router card.jpg
Binary files differ
diff --git a/Tex/Images/icons/pc software.jpg b/Tex/Images/icons/pc software.jpg
new file mode 100644
index 0000000..63e90c9
--- /dev/null
+++ b/Tex/Images/icons/pc software.jpg
Binary files differ
diff --git a/Tex/Images/icons/pc.jpg b/Tex/Images/icons/pc.jpg
new file mode 100644
index 0000000..d3214d6
--- /dev/null
+++ b/Tex/Images/icons/pc.jpg
Binary files differ
diff --git a/Tex/Images/icons/pc_video.jpg b/Tex/Images/icons/pc_video.jpg
new file mode 100644
index 0000000..76775c0
--- /dev/null
+++ b/Tex/Images/icons/pc_video.jpg
Binary files differ
diff --git a/Tex/Images/icons/pda.jpg b/Tex/Images/icons/pda.jpg
new file mode 100644
index 0000000..573a344
--- /dev/null
+++ b/Tex/Images/icons/pda.jpg
Binary files differ
diff --git a/Tex/Images/icons/phone fax.jpg b/Tex/Images/icons/phone fax.jpg
new file mode 100644
index 0000000..acd0151
--- /dev/null
+++ b/Tex/Images/icons/phone fax.jpg
Binary files differ
diff --git a/Tex/Images/icons/phone.jpg b/Tex/Images/icons/phone.jpg
new file mode 100644
index 0000000..51abc42
--- /dev/null
+++ b/Tex/Images/icons/phone.jpg
Binary files differ
diff --git a/Tex/Images/icons/pipe.jpg b/Tex/Images/icons/pipe.jpg
new file mode 100644
index 0000000..888dcd0
--- /dev/null
+++ b/Tex/Images/icons/pipe.jpg
Binary files differ
diff --git a/Tex/Images/icons/pix.jpg b/Tex/Images/icons/pix.jpg
new file mode 100644
index 0000000..cdd3741
--- /dev/null
+++ b/Tex/Images/icons/pix.jpg
Binary files differ
diff --git a/Tex/Images/icons/pmc.jpg b/Tex/Images/icons/pmc.jpg
new file mode 100644
index 0000000..f20fb77
--- /dev/null
+++ b/Tex/Images/icons/pmc.jpg
Binary files differ
diff --git a/Tex/Images/icons/printer.jpg b/Tex/Images/icons/printer.jpg
new file mode 100644
index 0000000..84c2c55
--- /dev/null
+++ b/Tex/Images/icons/printer.jpg
Binary files differ
diff --git a/Tex/Images/icons/programmable sw.jpg b/Tex/Images/icons/programmable sw.jpg
new file mode 100644
index 0000000..bb7c2dc
--- /dev/null
+++ b/Tex/Images/icons/programmable sw.jpg
Binary files differ
diff --git a/Tex/Images/icons/protocol translator.jpg b/Tex/Images/icons/protocol translator.jpg
new file mode 100644
index 0000000..eb7e611
--- /dev/null
+++ b/Tex/Images/icons/protocol translator.jpg
Binary files differ
diff --git a/Tex/Images/icons/pxf.jpg b/Tex/Images/icons/pxf.jpg
new file mode 100644
index 0000000..a0976e6
--- /dev/null
+++ b/Tex/Images/icons/pxf.jpg
Binary files differ
diff --git a/Tex/Images/icons/radio tower.jpg b/Tex/Images/icons/radio tower.jpg
new file mode 100644
index 0000000..9b11b5b
--- /dev/null
+++ b/Tex/Images/icons/radio tower.jpg
Binary files differ
diff --git a/Tex/Images/icons/ratemux.jpg b/Tex/Images/icons/ratemux.jpg
new file mode 100644
index 0000000..038bd4a
--- /dev/null
+++ b/Tex/Images/icons/ratemux.jpg
Binary files differ
diff --git a/Tex/Images/icons/relational database.jpg b/Tex/Images/icons/relational database.jpg
new file mode 100644
index 0000000..672f9d0
--- /dev/null
+++ b/Tex/Images/icons/relational database.jpg
Binary files differ
diff --git a/Tex/Images/icons/repeater.jpg b/Tex/Images/icons/repeater.jpg
new file mode 100644
index 0000000..b37533a
--- /dev/null
+++ b/Tex/Images/icons/repeater.jpg
Binary files differ
diff --git a/Tex/Images/icons/route switch processor.jpg b/Tex/Images/icons/route switch processor.jpg
new file mode 100644
index 0000000..a765340
--- /dev/null
+++ b/Tex/Images/icons/route switch processor.jpg
Binary files differ
diff --git a/Tex/Images/icons/router in bldg.jpg b/Tex/Images/icons/router in bldg.jpg
new file mode 100644
index 0000000..debd589
--- /dev/null
+++ b/Tex/Images/icons/router in bldg.jpg
Binary files differ
diff --git a/Tex/Images/icons/router w firewall.jpg b/Tex/Images/icons/router w firewall.jpg
new file mode 100644
index 0000000..deaec29
--- /dev/null
+++ b/Tex/Images/icons/router w firewall.jpg
Binary files differ
diff --git a/Tex/Images/icons/router w silicon switch.jpg b/Tex/Images/icons/router w silicon switch.jpg
new file mode 100644
index 0000000..8c48159
--- /dev/null
+++ b/Tex/Images/icons/router w silicon switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/router.jpg b/Tex/Images/icons/router.jpg
new file mode 100644
index 0000000..cc3450a
--- /dev/null
+++ b/Tex/Images/icons/router.jpg
Binary files differ
diff --git a/Tex/Images/icons/rps.jpg b/Tex/Images/icons/rps.jpg
new file mode 100644
index 0000000..2d5c279
--- /dev/null
+++ b/Tex/Images/icons/rps.jpg
Binary files differ
diff --git a/Tex/Images/icons/running man.jpg b/Tex/Images/icons/running man.jpg
new file mode 100644
index 0000000..74e6415
--- /dev/null
+++ b/Tex/Images/icons/running man.jpg
Binary files differ
diff --git a/Tex/Images/icons/satellite dish.jpg b/Tex/Images/icons/satellite dish.jpg
new file mode 100644
index 0000000..c259d51
--- /dev/null
+++ b/Tex/Images/icons/satellite dish.jpg
Binary files differ
diff --git a/Tex/Images/icons/satellite.jpg b/Tex/Images/icons/satellite.jpg
new file mode 100644
index 0000000..3ad94bc
--- /dev/null
+++ b/Tex/Images/icons/satellite.jpg
Binary files differ
diff --git a/Tex/Images/icons/sc2200 signalling controller.jpg b/Tex/Images/icons/sc2200 signalling controller.jpg
new file mode 100644
index 0000000..32c3742
--- /dev/null
+++ b/Tex/Images/icons/sc2200 signalling controller.jpg
Binary files differ
diff --git a/Tex/Images/icons/sc2200_vsc3000host.jpg b/Tex/Images/icons/sc2200_vsc3000host.jpg
new file mode 100644
index 0000000..a852340
--- /dev/null
+++ b/Tex/Images/icons/sc2200_vsc3000host.jpg
Binary files differ
diff --git a/Tex/Images/icons/scanner.jpg b/Tex/Images/icons/scanner.jpg
new file mode 100644
index 0000000..e517de0
--- /dev/null
+++ b/Tex/Images/icons/scanner.jpg
Binary files differ
diff --git a/Tex/Images/icons/server switch.jpg b/Tex/Images/icons/server switch.jpg
new file mode 100644
index 0000000..09d64e4
--- /dev/null
+++ b/Tex/Images/icons/server switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/server w pc router.jpg b/Tex/Images/icons/server w pc router.jpg
new file mode 100644
index 0000000..dd93584
--- /dev/null
+++ b/Tex/Images/icons/server w pc router.jpg
Binary files differ
diff --git a/Tex/Images/icons/service control.jpg b/Tex/Images/icons/service control.jpg
new file mode 100644
index 0000000..9c65d49
--- /dev/null
+++ b/Tex/Images/icons/service control.jpg
Binary files differ
diff --git a/Tex/Images/icons/sip proxy server.jpg b/Tex/Images/icons/sip proxy server.jpg
new file mode 100644
index 0000000..80d1669
--- /dev/null
+++ b/Tex/Images/icons/sip proxy server.jpg
Binary files differ
diff --git a/Tex/Images/icons/sitting woman.jpg b/Tex/Images/icons/sitting woman.jpg
new file mode 100644
index 0000000..438b592
--- /dev/null
+++ b/Tex/Images/icons/sitting woman.jpg
Binary files differ
diff --git a/Tex/Images/icons/small business.jpg b/Tex/Images/icons/small business.jpg
new file mode 100644
index 0000000..192e62a
--- /dev/null
+++ b/Tex/Images/icons/small business.jpg
Binary files differ
diff --git a/Tex/Images/icons/small hub.jpg b/Tex/Images/icons/small hub.jpg
new file mode 100644
index 0000000..e4ddf4d
--- /dev/null
+++ b/Tex/Images/icons/small hub.jpg
Binary files differ
diff --git a/Tex/Images/icons/softphone.jpg b/Tex/Images/icons/softphone.jpg
new file mode 100644
index 0000000..f2b4c3f
--- /dev/null
+++ b/Tex/Images/icons/softphone.jpg
Binary files differ
diff --git a/Tex/Images/icons/softswitch_pgw_mgc.jpg b/Tex/Images/icons/softswitch_pgw_mgc.jpg
new file mode 100644
index 0000000..08f69bd
--- /dev/null
+++ b/Tex/Images/icons/softswitch_pgw_mgc.jpg
Binary files differ
diff --git a/Tex/Images/icons/speaker.jpg b/Tex/Images/icons/speaker.jpg
new file mode 100644
index 0000000..72c2d9c
--- /dev/null
+++ b/Tex/Images/icons/speaker.jpg
Binary files differ
diff --git a/Tex/Images/icons/ssc.jpg b/Tex/Images/icons/ssc.jpg
new file mode 100644
index 0000000..dfe479b
--- /dev/null
+++ b/Tex/Images/icons/ssc.jpg
Binary files differ
diff --git a/Tex/Images/icons/ssl terminator.jpg b/Tex/Images/icons/ssl terminator.jpg
new file mode 100644
index 0000000..1117749
--- /dev/null
+++ b/Tex/Images/icons/ssl terminator.jpg
Binary files differ
diff --git a/Tex/Images/icons/standard host.jpg b/Tex/Images/icons/standard host.jpg
new file mode 100644
index 0000000..07f8e33
--- /dev/null
+++ b/Tex/Images/icons/standard host.jpg
Binary files differ
diff --git a/Tex/Images/icons/standing man icon.jpg b/Tex/Images/icons/standing man icon.jpg
new file mode 100644
index 0000000..907d8c7
--- /dev/null
+++ b/Tex/Images/icons/standing man icon.jpg
Binary files differ
diff --git a/Tex/Images/icons/standing woman.jpg b/Tex/Images/icons/standing woman.jpg
new file mode 100644
index 0000000..75ec0f9
--- /dev/null
+++ b/Tex/Images/icons/standing woman.jpg
Binary files differ
diff --git a/Tex/Images/icons/stb.jpg b/Tex/Images/icons/stb.jpg
new file mode 100644
index 0000000..3a1d759
--- /dev/null
+++ b/Tex/Images/icons/stb.jpg
Binary files differ
diff --git a/Tex/Images/icons/storage array.jpg b/Tex/Images/icons/storage array.jpg
new file mode 100644
index 0000000..a8ed8d8
--- /dev/null
+++ b/Tex/Images/icons/storage array.jpg
Binary files differ
diff --git a/Tex/Images/icons/storage router.jpg b/Tex/Images/icons/storage router.jpg
new file mode 100644
index 0000000..ab4a49c
--- /dev/null
+++ b/Tex/Images/icons/storage router.jpg
Binary files differ
diff --git a/Tex/Images/icons/stp.jpg b/Tex/Images/icons/stp.jpg
new file mode 100644
index 0000000..992a3a2
--- /dev/null
+++ b/Tex/Images/icons/stp.jpg
Binary files differ
diff --git a/Tex/Images/icons/streamer.jpg b/Tex/Images/icons/streamer.jpg
new file mode 100644
index 0000000..8f1c6de
--- /dev/null
+++ b/Tex/Images/icons/streamer.jpg
Binary files differ
diff --git a/Tex/Images/icons/sun workstation.jpg b/Tex/Images/icons/sun workstation.jpg
new file mode 100644
index 0000000..2fc2929
--- /dev/null
+++ b/Tex/Images/icons/sun workstation.jpg
Binary files differ
diff --git a/Tex/Images/icons/supercomputer.jpg b/Tex/Images/icons/supercomputer.jpg
new file mode 100644
index 0000000..c37752e
--- /dev/null
+++ b/Tex/Images/icons/supercomputer.jpg
Binary files differ
diff --git a/Tex/Images/icons/svx.jpg b/Tex/Images/icons/svx.jpg
new file mode 100644
index 0000000..a126909
--- /dev/null
+++ b/Tex/Images/icons/svx.jpg
Binary files differ
diff --git a/Tex/Images/icons/sw-based server.jpg b/Tex/Images/icons/sw-based server.jpg
new file mode 100644
index 0000000..f06a732
--- /dev/null
+++ b/Tex/Images/icons/sw-based server.jpg
Binary files differ
diff --git a/Tex/Images/icons/system controller.jpg b/Tex/Images/icons/system controller.jpg
new file mode 100644
index 0000000..fb72c8d
--- /dev/null
+++ b/Tex/Images/icons/system controller.jpg
Binary files differ
diff --git a/Tex/Images/icons/tablet.jpg b/Tex/Images/icons/tablet.jpg
new file mode 100644
index 0000000..4cf6980
--- /dev/null
+++ b/Tex/Images/icons/tablet.jpg
Binary files differ
diff --git a/Tex/Images/icons/tape array.jpg b/Tex/Images/icons/tape array.jpg
new file mode 100644
index 0000000..311671e
--- /dev/null
+++ b/Tex/Images/icons/tape array.jpg
Binary files differ
diff --git a/Tex/Images/icons/tdm router.jpg b/Tex/Images/icons/tdm router.jpg
new file mode 100644
index 0000000..39817a3
--- /dev/null
+++ b/Tex/Images/icons/tdm router.jpg
Binary files differ
diff --git a/Tex/Images/icons/telecommuter house rtr.jpg b/Tex/Images/icons/telecommuter house rtr.jpg
new file mode 100644
index 0000000..ab32f3f
--- /dev/null
+++ b/Tex/Images/icons/telecommuter house rtr.jpg
Binary files differ
diff --git a/Tex/Images/icons/telecommuter house.jpg b/Tex/Images/icons/telecommuter house.jpg
new file mode 100644
index 0000000..38f48e3
--- /dev/null
+++ b/Tex/Images/icons/telecommuter house.jpg
Binary files differ
diff --git a/Tex/Images/icons/telecomuter icon.jpg b/Tex/Images/icons/telecomuter icon.jpg
new file mode 100644
index 0000000..4924c32
--- /dev/null
+++ b/Tex/Images/icons/telecomuter icon.jpg
Binary files differ
diff --git a/Tex/Images/icons/telephone poles.jpg b/Tex/Images/icons/telephone poles.jpg
new file mode 100644
index 0000000..c39de7e
--- /dev/null
+++ b/Tex/Images/icons/telephone poles.jpg
Binary files differ
diff --git a/Tex/Images/icons/terminal.jpg b/Tex/Images/icons/terminal.jpg
new file mode 100644
index 0000000..fe6fc91
--- /dev/null
+++ b/Tex/Images/icons/terminal.jpg
Binary files differ
diff --git a/Tex/Images/icons/token ring.jpg b/Tex/Images/icons/token ring.jpg
new file mode 100644
index 0000000..f32e15e
--- /dev/null
+++ b/Tex/Images/icons/token ring.jpg
Binary files differ
diff --git a/Tex/Images/icons/transpath.jpg b/Tex/Images/icons/transpath.jpg
new file mode 100644
index 0000000..81b213a
--- /dev/null
+++ b/Tex/Images/icons/transpath.jpg
Binary files differ
diff --git a/Tex/Images/icons/truck.jpg b/Tex/Images/icons/truck.jpg
new file mode 100644
index 0000000..e0c0ec0
--- /dev/null
+++ b/Tex/Images/icons/truck.jpg
Binary files differ
diff --git a/Tex/Images/icons/turret.jpg b/Tex/Images/icons/turret.jpg
new file mode 100644
index 0000000..191f485
--- /dev/null
+++ b/Tex/Images/icons/turret.jpg
Binary files differ
diff --git a/Tex/Images/icons/tv.jpg b/Tex/Images/icons/tv.jpg
new file mode 100644
index 0000000..855bc5f
--- /dev/null
+++ b/Tex/Images/icons/tv.jpg
Binary files differ
diff --git a/Tex/Images/icons/ubr910.jpg b/Tex/Images/icons/ubr910.jpg
new file mode 100644
index 0000000..77bf2d3
--- /dev/null
+++ b/Tex/Images/icons/ubr910.jpg
Binary files differ
diff --git a/Tex/Images/icons/umg series.jpg b/Tex/Images/icons/umg series.jpg
new file mode 100644
index 0000000..2c570b6
--- /dev/null
+++ b/Tex/Images/icons/umg series.jpg
Binary files differ
diff --git a/Tex/Images/icons/unity server.jpg b/Tex/Images/icons/unity server.jpg
new file mode 100644
index 0000000..d370c92
--- /dev/null
+++ b/Tex/Images/icons/unity server.jpg
Binary files differ
diff --git a/Tex/Images/icons/university.jpg b/Tex/Images/icons/university.jpg
new file mode 100644
index 0000000..9a5b19a
--- /dev/null
+++ b/Tex/Images/icons/university.jpg
Binary files differ
diff --git a/Tex/Images/icons/unversal gateway.jpg b/Tex/Images/icons/unversal gateway.jpg
new file mode 100644
index 0000000..b61a724
--- /dev/null
+++ b/Tex/Images/icons/unversal gateway.jpg
Binary files differ
diff --git a/Tex/Images/icons/upc.jpg b/Tex/Images/icons/upc.jpg
new file mode 100644
index 0000000..d284e62
--- /dev/null
+++ b/Tex/Images/icons/upc.jpg
Binary files differ
diff --git a/Tex/Images/icons/ups.jpg b/Tex/Images/icons/ups.jpg
new file mode 100644
index 0000000..5ee778b
--- /dev/null
+++ b/Tex/Images/icons/ups.jpg
Binary files differ
diff --git a/Tex/Images/icons/vault.jpg b/Tex/Images/icons/vault.jpg
new file mode 100644
index 0000000..c6df69b
--- /dev/null
+++ b/Tex/Images/icons/vault.jpg
Binary files differ
diff --git a/Tex/Images/icons/video camera.jpg b/Tex/Images/icons/video camera.jpg
new file mode 100644
index 0000000..2886bc3
--- /dev/null
+++ b/Tex/Images/icons/video camera.jpg
Binary files differ
diff --git a/Tex/Images/icons/vip.jpg b/Tex/Images/icons/vip.jpg
new file mode 100644
index 0000000..7dd5206
--- /dev/null
+++ b/Tex/Images/icons/vip.jpg
Binary files differ
diff --git a/Tex/Images/icons/virtual layer switch.jpg b/Tex/Images/icons/virtual layer switch.jpg
new file mode 100644
index 0000000..8263783
--- /dev/null
+++ b/Tex/Images/icons/virtual layer switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/voice atm switch.jpg b/Tex/Images/icons/voice atm switch.jpg
new file mode 100644
index 0000000..d7e4c5a
--- /dev/null
+++ b/Tex/Images/icons/voice atm switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/voice gateway.jpg b/Tex/Images/icons/voice gateway.jpg
new file mode 100644
index 0000000..4cfa520
--- /dev/null
+++ b/Tex/Images/icons/voice gateway.jpg
Binary files differ
diff --git a/Tex/Images/icons/voice router.jpg b/Tex/Images/icons/voice router.jpg
new file mode 100644
index 0000000..f212f62
--- /dev/null
+++ b/Tex/Images/icons/voice router.jpg
Binary files differ
diff --git a/Tex/Images/icons/voice switch.jpg b/Tex/Images/icons/voice switch.jpg
new file mode 100644
index 0000000..f01e018
--- /dev/null
+++ b/Tex/Images/icons/voice switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/vpn concentrator.jpg b/Tex/Images/icons/vpn concentrator.jpg
new file mode 100644
index 0000000..4d3b822
--- /dev/null
+++ b/Tex/Images/icons/vpn concentrator.jpg
Binary files differ
diff --git a/Tex/Images/icons/vpn gateway.jpg b/Tex/Images/icons/vpn gateway.jpg
new file mode 100644
index 0000000..dda056f
--- /dev/null
+++ b/Tex/Images/icons/vpn gateway.jpg
Binary files differ
diff --git a/Tex/Images/icons/vsc 3000 virtual switch contrlr.jpg b/Tex/Images/icons/vsc 3000 virtual switch contrlr.jpg
new file mode 100644
index 0000000..0383b8f
--- /dev/null
+++ b/Tex/Images/icons/vsc 3000 virtual switch contrlr.jpg
Binary files differ
diff --git a/Tex/Images/icons/wae.jpg b/Tex/Images/icons/wae.jpg
new file mode 100644
index 0000000..a98949b
--- /dev/null
+++ b/Tex/Images/icons/wae.jpg
Binary files differ
diff --git a/Tex/Images/icons/wavelength router.jpg b/Tex/Images/icons/wavelength router.jpg
new file mode 100644
index 0000000..a755267
--- /dev/null
+++ b/Tex/Images/icons/wavelength router.jpg
Binary files differ
diff --git a/Tex/Images/icons/web browser.jpg b/Tex/Images/icons/web browser.jpg
new file mode 100644
index 0000000..f48715d
--- /dev/null
+++ b/Tex/Images/icons/web browser.jpg
Binary files differ
diff --git a/Tex/Images/icons/web cluster.jpg b/Tex/Images/icons/web cluster.jpg
new file mode 100644
index 0000000..e8a7824
--- /dev/null
+++ b/Tex/Images/icons/web cluster.jpg
Binary files differ
diff --git a/Tex/Images/icons/wi-fi tag.jpg b/Tex/Images/icons/wi-fi tag.jpg
new file mode 100644
index 0000000..6c46aa6
--- /dev/null
+++ b/Tex/Images/icons/wi-fi tag.jpg
Binary files differ
diff --git a/Tex/Images/icons/wireless bridge.jpg b/Tex/Images/icons/wireless bridge.jpg
new file mode 100644
index 0000000..dc35667
--- /dev/null
+++ b/Tex/Images/icons/wireless bridge.jpg
Binary files differ
diff --git a/Tex/Images/icons/wireless location appliance.jpg b/Tex/Images/icons/wireless location appliance.jpg
new file mode 100644
index 0000000..3d5d250
--- /dev/null
+++ b/Tex/Images/icons/wireless location appliance.jpg
Binary files differ
diff --git a/Tex/Images/icons/wireless router.jpg b/Tex/Images/icons/wireless router.jpg
new file mode 100644
index 0000000..9336115
--- /dev/null
+++ b/Tex/Images/icons/wireless router.jpg
Binary files differ
diff --git a/Tex/Images/icons/wireless transport.jpg b/Tex/Images/icons/wireless transport.jpg
new file mode 100644
index 0000000..ad605ac
--- /dev/null
+++ b/Tex/Images/icons/wireless transport.jpg
Binary files differ
diff --git a/Tex/Images/icons/wireless.jpg b/Tex/Images/icons/wireless.jpg
new file mode 100644
index 0000000..a5c0d6c
--- /dev/null
+++ b/Tex/Images/icons/wireless.jpg
Binary files differ
diff --git a/Tex/Images/icons/wism.jpg b/Tex/Images/icons/wism.jpg
new file mode 100644
index 0000000..ca8500e
--- /dev/null
+++ b/Tex/Images/icons/wism.jpg
Binary files differ
diff --git a/Tex/Images/icons/wlan controller.jpg b/Tex/Images/icons/wlan controller.jpg
new file mode 100644
index 0000000..71d2143
--- /dev/null
+++ b/Tex/Images/icons/wlan controller.jpg
Binary files differ
diff --git a/Tex/Images/icons/workgroup director.jpg b/Tex/Images/icons/workgroup director.jpg
new file mode 100644
index 0000000..5ae0cfd
--- /dev/null
+++ b/Tex/Images/icons/workgroup director.jpg
Binary files differ
diff --git a/Tex/Images/icons/workgroup switch.jpg b/Tex/Images/icons/workgroup switch.jpg
new file mode 100644
index 0000000..4203106
--- /dev/null
+++ b/Tex/Images/icons/workgroup switch.jpg
Binary files differ
diff --git a/Tex/Images/icons/workstation.jpg b/Tex/Images/icons/workstation.jpg
new file mode 100644
index 0000000..fdf32d1
--- /dev/null
+++ b/Tex/Images/icons/workstation.jpg
Binary files differ
diff --git a/Tex/Images/icons/www server.jpg b/Tex/Images/icons/www server.jpg
new file mode 100644
index 0000000..52ac068
--- /dev/null
+++ b/Tex/Images/icons/www server.jpg
Binary files differ
diff --git a/Tex/Images/template.graphml b/Tex/Images/template.graphml
new file mode 100644
index 0000000..a65bd43
--- /dev/null
+++ b/Tex/Images/template.graphml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+ <!--Created by yFiles for Java 2.9-->
+ <key for="graphml" id="d0" yfiles.type="resources"/>
+ <key for="port" id="d1" yfiles.type="portgraphics"/>
+ <key for="port" id="d2" yfiles.type="portgeometry"/>
+ <key for="port" id="d3" yfiles.type="portuserdata"/>
+ <key attr.name="url" attr.type="string" for="node" id="d4"/>
+ <key attr.name="description" attr.type="string" for="node" id="d5"/>
+ <key for="node" id="d6" yfiles.type="nodegraphics"/>
+ <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+ <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+ <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+ <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+ <graph edgedefault="directed" id="G">
+ <data key="d7"/>
+ <node id="n0">
+ <data key="d5"/>
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="30.0" width="598.0" x="12.0" y="29.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="21.4609375" modelName="custom" textColor="#000000" visible="true" width="209.2099609375" x="194.39501953125" y="4.26953125">lorem ipsum blah blah blah<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="rectangle"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ </graph>
+ <data key="d0">
+ <y:Resources/>
+ </data>
+</graphml>
diff --git a/Tex/Images/template.png b/Tex/Images/template.png
new file mode 100644
index 0000000..460d665
--- /dev/null
+++ b/Tex/Images/template.png
Binary files differ
diff --git a/Tex/Master/Master.acn b/Tex/Master/Master.acn
index 6776b0d..148206c 100644
--- a/Tex/Master/Master.acn
+++ b/Tex/Master/Master.acn
@@ -1,453 +1,451 @@
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{1}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{1}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{1}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{CEPT?\glossaryentryfield{cept}{\glsnamefont{CEPT}}{Conf\'{e}rence Europ\'{e}enne des Administrations des Postes et des T\'{e}l\'{e}communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{TACS?\glossaryentryfield{tacs}{\glsnamefont{TACS}}{Total Access Communication System}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{NMT?\glossaryentryfield{nmt}{\glsnamefont{NMT}}{Northern Telecomunication}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{MoU?\glossaryentryfield{MoU}{\glsnamefont{MoU}}{Memorandum of Understanding}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{CEPT?\glossaryentryfield{cept}{\glsnamefont{CEPT}}{Conf\'{e}rence Europ\'{e}enne des Administrations des Postes et des T\'{e}l\'{e}communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{DCS1800?\glossaryentryfield{dcs1800}{\glsnamefont{DCS1800}}{Digital Cellular System 1800}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{STC?\glossaryentryfield{stc}{\glsnamefont{STC}}{Sub Technical Committee}{\relax }|setentrycounter[]{page}\glsnumberformat}{3}
-\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{ARIB?\glossaryentryfield{arib}{\glsnamefont{ARIB}}{Association of Radio Industries and Businesses}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{ATIS?\glossaryentryfield{atis}{\glsnamefont{ATIS}}{Alliance for Telecommunications Industry Solutions}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{TTA?\glossaryentryfield{tta}{\glsnamefont{TTA}}{Telecommunications Technology Association}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{TTC?\glossaryentryfield{ttc}{\glsnamefont{TTC}}{Telecommunications Technology Committee}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{ITU?\glossaryentryfield{itu}{\glsnamefont{ITU}}{International Telecomunication Union}{\relax }|setentrycounter[]{page}\glsnumberformat}{4}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{GPRS?\glossaryentryfield{gprs}{\glsnamefont{GPRS}}{General Packet Radio Service}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{EDGE?\glossaryentryfield{edge}{\glsnamefont{EDGE}}{Enhanced Data Rates for GSM Evolution}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{UMTS?\glossaryentryfield{umts}{\glsnamefont{UMTS}}{Universal Mobile Telecomunications System}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{HSDPA?\glossaryentryfield{hsdpa}{\glsnamefont{HSDPA}}{High Speed Downlink Packet Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{HSDPA?\glossaryentryfield{hsdpa}{\glsnamefont{HSDPA}}{High Speed Downlink Packet Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{HSUPA?\glossaryentryfield{hsupa}{\glsnamefont{HSUPA}}{High Speed Uplink Packet Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{HSPA?\glossaryentryfield{hspa}{\glsnamefont{HSPA}}{High Speed Packet Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{PSTN?\glossaryentryfield{pstn}{\glsnamefont{PSTN}}{Public Standard Telephone Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{5}
-\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{VAS?\glossaryentryfield{vas}{\glsnamefont{VAS}}{value-added service}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{OMS?\glossaryentryfield{oms}{\glsnamefont{OMS}}{Operation and Maintainance Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{6}
-\glossaryentry{DTMF?\glossaryentryfield{dtmf}{\glsnamefont{DTMF}}{Dual Tone Multi Frequency}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{SMS?\glossaryentryfield{sms}{\glsnamefont{SMS}}{Short Message Service}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{PLMS?\glossaryentryfield{plmn}{\glsnamefont{PLMS}}{Public Land Mobile Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{PDA?\glossaryentryfield{pda}{\glsnamefont{PDA}}{Personal Digital Assistant}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{7}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{EEPROM?\glossaryentryfield{eeprom}{\glsnamefont{EEPROM}}{Electrically Erasable Programmable Read-Only Memory}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{Kc?\glossaryentryfield{kc}{\glsnamefont{Kc}}{Cyphering Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{Kc?\glossaryentryfield{kc}{\glsnamefont{Kc}}{Cyphering Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{PIN?\glossaryentryfield{pin}{\glsnamefont{PIN}}{Personal Identification Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MSIN?\glossaryentryfield{msin}{\glsnamefont{MSIN}}{Mobile Subscriber Identification Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{HNI?\glossaryentryfield{hni}{\glsnamefont{HNI}}{Home Network Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{PLMS?\glossaryentryfield{plmn}{\glsnamefont{PLMS}}{Public Land Mobile Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{ITU?\glossaryentryfield{itu}{\glsnamefont{ITU}}{International Telecomunication Union}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MSIN?\glossaryentryfield{msin}{\glsnamefont{MSIN}}{Mobile Subscriber Identification Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MSIN?\glossaryentryfield{msin}{\glsnamefont{MSIN}}{Mobile Subscriber Identification Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{NMSI?\glossaryentryfield{nmsi}{\glsnamefont{NMSI}}{National Mobile Subscriber Identity}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{PSTN?\glossaryentryfield{pstn}{\glsnamefont{PSTN}}{Public Standard Telephone Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{EIR?\glossaryentryfield{eir}{\glsnamefont{EIR}}{Equipment Identity Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{SMSC?\glossaryentryfield{smsc}{\glsnamefont{SMSC}}{Short Message Service Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{ISDN?\glossaryentryfield{isdn}{\glsnamefont{ISDN}}{Integrated Services Digital Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{PLMS?\glossaryentryfield{plmn}{\glsnamefont{PLMS}}{Public Land Mobile Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{CC?\glossaryentryfield{cc}{\glsnamefont{CC}}{Call Control}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{MM?\glossaryentryfield{mm}{\glsnamefont{MM}}{Mobility Management}{\relax }|setentrycounter[]{page}\glsnumberformat}{9}
-\glossaryentry{CC?\glossaryentryfield{cc}{\glsnamefont{CC}}{Call Control}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{PSTN?\glossaryentryfield{pstn}{\glsnamefont{PSTN}}{Public Standard Telephone Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MM?\glossaryentryfield{mm}{\glsnamefont{MM}}{Mobility Management}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSISDN?\glossaryentryfield{msisdn}{\glsnamefont{MSISDN}}{Mobile Subscriber Integrated Services Digital Network Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{MSRN?\glossaryentryfield{msrn}{\glsnamefont{MSRN}}{Mobile Station Roaming Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{10}
-\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MSISDN?\glossaryentryfield{msisdn}{\glsnamefont{MSISDN}}{Mobile Subscriber Integrated Services Digital Network Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{TMSI?\glossaryentryfield{tmsi}{\glsnamefont{TMSI}}{Temporary IMSI}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{EIR?\glossaryentryfield{eir}{\glsnamefont{EIR}}{Equipment Identity Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{CEIR?\glossaryentryfield{ceir}{\glsnamefont{CEIR}}{Central Equipment Identity Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{12}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{UMTS?\glossaryentryfield{umts}{\glsnamefont{UMTS}}{Universal Mobile Telecomunications System}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{SS-7?\glossaryentryfield{ss7}{\glsnamefont{SS-7}}{Signaling System 7}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{LBS?\glossaryentryfield{lbs}{\glsnamefont{LBS}}{Location Based Services}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{LBS?\glossaryentryfield{lbs}{\glsnamefont{LBS}}{Location Based Services}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter[]{page}\glsnumberformat}{14}
-\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{CAMEL?\glossaryentryfield{camel}{\glsnamefont{CAMEL}}{Customized Applications for Mobile network Enhanced Logic}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{CAMEL?\glossaryentryfield{camel}{\glsnamefont{CAMEL}}{Customized Applications for Mobile network Enhanced Logic}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{HTTP?\glossaryentryfield{http}{\glsnamefont{HTTP}}{Hyper Text Transfer Protocol}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{ARFCN?\glossaryentryfield{arfcn}{\glsnamefont{ARFCN}}{Absolute Radio Frequency Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{15}
-\glossaryentry{ARFCN?\glossaryentryfield{arfcn}{\glsnamefont{ARFCN}}{Absolute Radio Frequency Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{17}
-\glossaryentry{ARFCN?\glossaryentryfield{arfcn}{\glsnamefont{ARFCN}}{Absolute Radio Frequency Number}{\relax }|setentrycounter[]{page}\glsnumberformat}{17}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{17}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{17}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{17}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{CI?\glossaryentryfield{ci}{\glsnamefont{CI}}{Cell Identity}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{18}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{AGCH?\glossaryentryfield{agch}{\glsnamefont{AGCH}}{Access Grand Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{TMSI?\glossaryentryfield{tmsi}{\glsnamefont{TMSI}}{Temporary IMSI}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{PCH?\glossaryentryfield{pch}{\glsnamefont{PCH}}{Paging Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{20}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{SACCH?\glossaryentryfield{sacch}{\glsnamefont{SACCH}}{Slow Access Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{FACCH?\glossaryentryfield{facch}{\glsnamefont{FACCH}}{Fast Access Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter[]{page}\glsnumberformat}{21}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{Kc?\glossaryentryfield{kc}{\glsnamefont{Kc}}{Cyphering Key}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{22}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{FDMA?\glossaryentryfield{fdma}{\glsnamefont{FDMA}}{Frequency Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{FDMA?\glossaryentryfield{fdma}{\glsnamefont{FDMA}}{Frequency Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{FDMA?\glossaryentryfield{fdma}{\glsnamefont{FDMA}}{Frequency Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{23}
-\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{24}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{SF?\glossaryentryfield{sf}{\glsnamefont{SF}}{Stealing Flag}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{FACCH?\glossaryentryfield{facch}{\glsnamefont{FACCH}}{Fast Access Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{FCCH?\glossaryentryfield{fcch}{\glsnamefont{FCCH}}{Frequency Correction Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{26}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{27}
-\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{27}
-\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{27}
-\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter[]{page}\glsnumberformat}{27}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{FACCH?\glossaryentryfield{facch}{\glsnamefont{FACCH}}{Fast Access Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{SACCH?\glossaryentryfield{sacch}{\glsnamefont{SACCH}}{Slow Access Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{FCCH?\glossaryentryfield{fcch}{\glsnamefont{FCCH}}{Frequency Correction Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{PCH?\glossaryentryfield{pch}{\glsnamefont{PCH}}{Paging Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{TMSI?\glossaryentryfield{tmsi}{\glsnamefont{TMSI}}{Temporary IMSI}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{28}
-\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{PCH?\glossaryentryfield{pch}{\glsnamefont{PCH}}{Paging Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{AGCH?\glossaryentryfield{agch}{\glsnamefont{AGCH}}{Access Grand Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{29}
-\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{ITU?\glossaryentryfield{itu}{\glsnamefont{ITU}}{International Telecomunication Union}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{GMSK?\glossaryentryfield{gmsk}{\glsnamefont{GMSK}}{Gaussian Minimum Shift Keying}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{HDLC?\glossaryentryfield{hdlc}{\glsnamefont{HDLC}}{High Level Data Link Control}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{SS-7?\glossaryentryfield{ss7}{\glsnamefont{SS-7}}{Signaling System 7}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{LAPD?\glossaryentryfield{lapd}{\glsnamefont{LAPD}}{Link Access Procedure, D Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{HDLC?\glossaryentryfield{hdlc}{\glsnamefont{HDLC}}{High Level Data Link Control}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{LAPD$_m$?\glossaryentryfield{lapdm}{\glsnamefont{LAPD$_m$}}{LAPD Mobile}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{ISDN?\glossaryentryfield{isdn}{\glsnamefont{ISDN}}{Integrated Services Digital Network}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{LAPD$_m$?\glossaryentryfield{lapdm}{\glsnamefont{LAPD$_m$}}{LAPD Mobile}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{LAPD?\glossaryentryfield{lapd}{\glsnamefont{LAPD}}{Link Access Procedure, D Channel}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{MTP 2/SS7?\glossaryentryfield{mtp2}{\glsnamefont{MTP 2/SS7}}{Message Transfer Part 2/SS7}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{LAPD$_m$?\glossaryentryfield{lapdm}{\glsnamefont{LAPD$_m$}}{LAPD Mobile}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{RR?\glossaryentryfield{rr}{\glsnamefont{RR}}{Radio Resource}{\relax }|setentrycounter[]{page}\glsnumberformat}{30}
-\glossaryentry{SS-7?\glossaryentryfield{ss7}{\glsnamefont{SS-7}}{Signaling System 7}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{MM?\glossaryentryfield{mm}{\glsnamefont{MM}}{Mobility Management}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{CC?\glossaryentryfield{cc}{\glsnamefont{CC}}{Call Control}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{RR?\glossaryentryfield{rr}{\glsnamefont{RR}}{Radio Resource}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{32}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{LAI?\glossaryentryfield{lai}{\glsnamefont{LAI}}{Location Area Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{33}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{LAI?\glossaryentryfield{lai}{\glsnamefont{LAI}}{Location Area Identifier}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{35}
-\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{BMI?\glossaryentryfield{bmi}{\glsnamefont{BMI}}{Bundesminiterium des Inneren}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{BKA?\glossaryentryfield{bka}{\glsnamefont{BKA}}{Bundeskriminalamt}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{BGS?\glossaryentryfield{bgs}{\glsnamefont{BGS}}{Bundesgrenzschutz}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{36}
-\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter[]{page}\glsnumberformat}{37}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{1}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{1}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{1}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{CEPT?\glossaryentryfield{cept}{\glsnamefont{CEPT}}{Conf\'{e}rence Europ\'{e}enne des Administrations des Postes et des T\'{e}l\'{e}communications}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{TACS?\glossaryentryfield{tacs}{\glsnamefont{TACS}}{Total Access Communication System}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{NMT?\glossaryentryfield{nmt}{\glsnamefont{NMT}}{Northern Telecomunication}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{MoU?\glossaryentryfield{MoU}{\glsnamefont{MoU}}{Memorandum of Understanding}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{CEPT?\glossaryentryfield{cept}{\glsnamefont{CEPT}}{Conf\'{e}rence Europ\'{e}enne des Administrations des Postes et des T\'{e}l\'{e}communications}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{DCS1800?\glossaryentryfield{dcs1800}{\glsnamefont{DCS1800}}{Digital Cellular System 1800}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{STC?\glossaryentryfield{stc}{\glsnamefont{STC}}{Sub Technical Committee}{\relax }|setentrycounter{page}\glsnumberformat}{3}
+\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{ARIB?\glossaryentryfield{arib}{\glsnamefont{ARIB}}{Association of Radio Industries and Businesses}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{ATIS?\glossaryentryfield{atis}{\glsnamefont{ATIS}}{Alliance for Telecommunications Industry Solutions}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{TTA?\glossaryentryfield{tta}{\glsnamefont{TTA}}{Telecommunications Technology Association}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{TTC?\glossaryentryfield{ttc}{\glsnamefont{TTC}}{Telecommunications Technology Committee}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{ITU?\glossaryentryfield{itu}{\glsnamefont{ITU}}{International Telecomunication Union}{\relax }|setentrycounter{page}\glsnumberformat}{4}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{GPRS?\glossaryentryfield{gprs}{\glsnamefont{GPRS}}{General Packet Radio Service}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{EDGE?\glossaryentryfield{edge}{\glsnamefont{EDGE}}{Enhanced Data Rates for GSM Evolution}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{UMTS?\glossaryentryfield{umts}{\glsnamefont{UMTS}}{Universal Mobile Telecomunications System}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{HSDPA?\glossaryentryfield{hsdpa}{\glsnamefont{HSDPA}}{High Speed Downlink Packet Access}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{HSDPA?\glossaryentryfield{hsdpa}{\glsnamefont{HSDPA}}{High Speed Downlink Packet Access}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{HSUPA?\glossaryentryfield{hsupa}{\glsnamefont{HSUPA}}{High Speed Uplink Packet Access}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{HSPA?\glossaryentryfield{hspa}{\glsnamefont{HSPA}}{High Speed Packet Access}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{PSTN?\glossaryentryfield{pstn}{\glsnamefont{PSTN}}{Public Standard Telephone Network}{\relax }|setentrycounter{page}\glsnumberformat}{5}
+\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{VAS?\glossaryentryfield{vas}{\glsnamefont{VAS}}{value-added service}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{OMS?\glossaryentryfield{oms}{\glsnamefont{OMS}}{Operation and Maintainance Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{6}
+\glossaryentry{DTMF?\glossaryentryfield{dtmf}{\glsnamefont{DTMF}}{Dual Tone Multi Frequency}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{SMS?\glossaryentryfield{sms}{\glsnamefont{SMS}}{Short Message Service}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{PLMS?\glossaryentryfield{plmn}{\glsnamefont{PLMS}}{Public Land Mobile Network}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{PDA?\glossaryentryfield{pda}{\glsnamefont{PDA}}{Personal Digital Assistant}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{7}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{EEPROM?\glossaryentryfield{eeprom}{\glsnamefont{EEPROM}}{Electrically Erasable Programmable Read-Only Memory}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{Kc?\glossaryentryfield{kc}{\glsnamefont{Kc}}{Cyphering Key}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{Kc?\glossaryentryfield{kc}{\glsnamefont{Kc}}{Cyphering Key}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{PIN?\glossaryentryfield{pin}{\glsnamefont{PIN}}{Personal Identification Number}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MSIN?\glossaryentryfield{msin}{\glsnamefont{MSIN}}{Mobile Subscriber Identification Number}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{HNI?\glossaryentryfield{hni}{\glsnamefont{HNI}}{Home Network Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{PLMS?\glossaryentryfield{plmn}{\glsnamefont{PLMS}}{Public Land Mobile Network}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter{page}\glsnumberformat}{8}
+\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MCC?\glossaryentryfield{mcc}{\glsnamefont{MCC}}{Mobile Country Code}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{ITU?\glossaryentryfield{itu}{\glsnamefont{ITU}}{International Telecomunication Union}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MSIN?\glossaryentryfield{msin}{\glsnamefont{MSIN}}{Mobile Subscriber Identification Number}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MNC?\glossaryentryfield{mnc}{\glsnamefont{MNC}}{Mobile Network Code}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MSIN?\glossaryentryfield{msin}{\glsnamefont{MSIN}}{Mobile Subscriber Identification Number}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{NMSI?\glossaryentryfield{nmsi}{\glsnamefont{NMSI}}{National Mobile Subscriber Identity}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{PSTN?\glossaryentryfield{pstn}{\glsnamefont{PSTN}}{Public Standard Telephone Network}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{EIR?\glossaryentryfield{eir}{\glsnamefont{EIR}}{Equipment Identity Register}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{SMSC?\glossaryentryfield{smsc}{\glsnamefont{SMSC}}{Short Message Service Center}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{ISDN?\glossaryentryfield{isdn}{\glsnamefont{ISDN}}{Integrated Services Digital Network}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{PLMS?\glossaryentryfield{plmn}{\glsnamefont{PLMS}}{Public Land Mobile Network}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{CC?\glossaryentryfield{cc}{\glsnamefont{CC}}{Call Control}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{MM?\glossaryentryfield{mm}{\glsnamefont{MM}}{Mobility Management}{\relax }|setentrycounter{page}\glsnumberformat}{9}
+\glossaryentry{CC?\glossaryentryfield{cc}{\glsnamefont{CC}}{Call Control}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{PSTN?\glossaryentryfield{pstn}{\glsnamefont{PSTN}}{Public Standard Telephone Network}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MM?\glossaryentryfield{mm}{\glsnamefont{MM}}{Mobility Management}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSISDN?\glossaryentryfield{msisdn}{\glsnamefont{MSISDN}}{Mobile Subscriber Integrated Services Digital Network Number}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{MSRN?\glossaryentryfield{msrn}{\glsnamefont{MSRN}}{Mobile Station Roaming Number}{\relax }|setentrycounter{page}\glsnumberformat}{10}
+\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MSISDN?\glossaryentryfield{msisdn}{\glsnamefont{MSISDN}}{Mobile Subscriber Integrated Services Digital Network Number}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{TMSI?\glossaryentryfield{tmsi}{\glsnamefont{TMSI}}{Temporary IMSI}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{VLR?\glossaryentryfield{vlr}{\glsnamefont{VLR}}{Visitor Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{EIR?\glossaryentryfield{eir}{\glsnamefont{EIR}}{Equipment Identity Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{CEIR?\glossaryentryfield{ceir}{\glsnamefont{CEIR}}{Central Equipment Identity Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{HLR?\glossaryentryfield{hlr}{\glsnamefont{HLR}}{Home Location Register}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{12}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{AC?\glossaryentryfield{ac}{\glsnamefont{AC}}{Authentication Center}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{UMTS?\glossaryentryfield{umts}{\glsnamefont{UMTS}}{Universal Mobile Telecomunications System}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{SS-7?\glossaryentryfield{ss7}{\glsnamefont{SS-7}}{Signaling System 7}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{LBS?\glossaryentryfield{lbs}{\glsnamefont{LBS}}{Location Based Services}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{LBS?\glossaryentryfield{lbs}{\glsnamefont{LBS}}{Location Based Services}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{IN?\glossaryentryfield{in}{\glsnamefont{IN}}{Intelligent Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter{page}\glsnumberformat}{14}
+\glossaryentry{SCP?\glossaryentryfield{scp}{\glsnamefont{SCP}}{Service Control Point}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{ETSI?\glossaryentryfield{etsi}{\glsnamefont{ETSI}}{European Communication Standards Institute}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{CAMEL?\glossaryentryfield{camel}{\glsnamefont{CAMEL}}{Customized Applications for Mobile network Enhanced Logic}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{CAMEL?\glossaryentryfield{camel}{\glsnamefont{CAMEL}}{Customized Applications for Mobile network Enhanced Logic}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{HTTP?\glossaryentryfield{http}{\glsnamefont{HTTP}}{Hyper Text Transfer Protocol}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{ARFCN?\glossaryentryfield{arfcn}{\glsnamefont{ARFCN}}{Absolute Radio Frequency Number}{\relax }|setentrycounter{page}\glsnumberformat}{15}
+\glossaryentry{ARFCN?\glossaryentryfield{arfcn}{\glsnamefont{ARFCN}}{Absolute Radio Frequency Number}{\relax }|setentrycounter{page}\glsnumberformat}{17}
+\glossaryentry{ARFCN?\glossaryentryfield{arfcn}{\glsnamefont{ARFCN}}{Absolute Radio Frequency Number}{\relax }|setentrycounter{page}\glsnumberformat}{17}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{17}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{17}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{17}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{CI?\glossaryentryfield{ci}{\glsnamefont{CI}}{Cell Identity}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{18}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSS?\glossaryentryfield{bss}{\glsnamefont{BSS}}{Basestation Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{AGCH?\glossaryentryfield{agch}{\glsnamefont{AGCH}}{Access Grand Channel}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{TMSI?\glossaryentryfield{tmsi}{\glsnamefont{TMSI}}{Temporary IMSI}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{LA?\glossaryentryfield{la}{\glsnamefont{LA}}{Location Area}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{PCH?\glossaryentryfield{pch}{\glsnamefont{PCH}}{Paging Channel}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{20}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{SACCH?\glossaryentryfield{sacch}{\glsnamefont{SACCH}}{Slow Access Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{FACCH?\glossaryentryfield{facch}{\glsnamefont{FACCH}}{Fast Access Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{TRAU?\glossaryentryfield{trau}{\glsnamefont{TRAU}}{Transcoding Rate and Adaption Unit}{\relax }|setentrycounter{page}\glsnumberformat}{21}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{Ki?\glossaryentryfield{ki}{\glsnamefont{Ki}}{Secret Key}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{Kc?\glossaryentryfield{kc}{\glsnamefont{Kc}}{Cyphering Key}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{ME?\glossaryentryfield{me}{\glsnamefont{ME}}{Mobile Equipment}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{22}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{FDMA?\glossaryentryfield{fdma}{\glsnamefont{FDMA}}{Frequency Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{FDMA?\glossaryentryfield{fdma}{\glsnamefont{FDMA}}{Frequency Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{FDMA?\glossaryentryfield{fdma}{\glsnamefont{FDMA}}{Frequency Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{23}
+\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{24}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{SF?\glossaryentryfield{sf}{\glsnamefont{SF}}{Stealing Flag}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{FACCH?\glossaryentryfield{facch}{\glsnamefont{FACCH}}{Fast Access Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{FCCH?\glossaryentryfield{fcch}{\glsnamefont{FCCH}}{Frequency Correction Channel}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter{page}\glsnumberformat}{26}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{27}
+\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter{page}\glsnumberformat}{27}
+\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter{page}\glsnumberformat}{27}
+\glossaryentry{TDMA?\glossaryentryfield{tdma}{\glsnamefont{TDMA}}{Time Division Multiple Access}{\relax }|setentrycounter{page}\glsnumberformat}{27}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{FACCH?\glossaryentryfield{facch}{\glsnamefont{FACCH}}{Fast Access Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{SACCH?\glossaryentryfield{sacch}{\glsnamefont{SACCH}}{Slow Access Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{TCH?\glossaryentryfield{tch}{\glsnamefont{TCH}}{Traffic Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{SCH?\glossaryentryfield{sch}{\glsnamefont{SCH}}{Signalling Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{FCCH?\glossaryentryfield{fcch}{\glsnamefont{FCCH}}{Frequency Correction Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{PCH?\glossaryentryfield{pch}{\glsnamefont{PCH}}{Paging Channel}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{TMSI?\glossaryentryfield{tmsi}{\glsnamefont{TMSI}}{Temporary IMSI}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{28}
+\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{PCH?\glossaryentryfield{pch}{\glsnamefont{PCH}}{Paging Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{AGCH?\glossaryentryfield{agch}{\glsnamefont{AGCH}}{Access Grand Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{RACH?\glossaryentryfield{rach}{\glsnamefont{RACH}}{Random Access Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{SDCCH?\glossaryentryfield{sdcch}{\glsnamefont{SDCCH}}{Standalone Digital Control Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter{page}\glsnumberformat}{29}
+\glossaryentry{BCCH?\glossaryentryfield{bcch}{\glsnamefont{BCCH}}{Broadcast Channel}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{ITU?\glossaryentryfield{itu}{\glsnamefont{ITU}}{International Telecomunication Union}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{GMSK?\glossaryentryfield{gmsk}{\glsnamefont{GMSK}}{Gaussian Minimum Shift Keying}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{HDLC?\glossaryentryfield{hdlc}{\glsnamefont{HDLC}}{High Level Data Link Control}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{SS-7?\glossaryentryfield{ss7}{\glsnamefont{SS-7}}{Signaling System 7}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{LAPD?\glossaryentryfield{lapd}{\glsnamefont{LAPD}}{Link Access Procedure, D Channel}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{HDLC?\glossaryentryfield{hdlc}{\glsnamefont{HDLC}}{High Level Data Link Control}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{LAPD$_m$?\glossaryentryfield{lapdm}{\glsnamefont{LAPD$_m$}}{LAPD Mobile}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{ISDN?\glossaryentryfield{isdn}{\glsnamefont{ISDN}}{Integrated Services Digital Network}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{LAPD$_m$?\glossaryentryfield{lapdm}{\glsnamefont{LAPD$_m$}}{LAPD Mobile}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{LAPD?\glossaryentryfield{lapd}{\glsnamefont{LAPD}}{Link Access Procedure, D Channel}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{MTP 2/SS7?\glossaryentryfield{mtp2}{\glsnamefont{MTP 2/SS7}}{Message Transfer Part 2/SS7}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{LAPD$_m$?\glossaryentryfield{lapdm}{\glsnamefont{LAPD$_m$}}{LAPD Mobile}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{3GPP?\glossaryentryfield{3gpp}{\glsnamefont{3GPP}}{Third Generation Partnership Project}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{BSC?\glossaryentryfield{bsc}{\glsnamefont{BSC}}{Base Station Controller}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{MSC?\glossaryentryfield{msc}{\glsnamefont{MSC}}{Mobile Switching Center}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{RR?\glossaryentryfield{rr}{\glsnamefont{RR}}{Radio Resource}{\relax }|setentrycounter{page}\glsnumberformat}{30}
+\glossaryentry{SS-7?\glossaryentryfield{ss7}{\glsnamefont{SS-7}}{Signaling System 7}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{MM?\glossaryentryfield{mm}{\glsnamefont{MM}}{Mobility Management}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{CC?\glossaryentryfield{cc}{\glsnamefont{CC}}{Call Control}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{RR?\glossaryentryfield{rr}{\glsnamefont{RR}}{Radio Resource}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{NSS?\glossaryentryfield{nss}{\glsnamefont{NSS}}{Network Subsystem}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{32}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{LAI?\glossaryentryfield{lai}{\glsnamefont{LAI}}{Location Area Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{GSM?\glossaryentryfield{gsm}{\glsnamefont{GSM}}{Global System for Mobile Communications}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{33}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{IMEI?\glossaryentryfield{imei}{\glsnamefont{IMEI}}{International Mobile Equipment Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{BTS?\glossaryentryfield{bts}{\glsnamefont{BTS}}{Base Station Transceiver}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{LAI?\glossaryentryfield{lai}{\glsnamefont{LAI}}{Location Area Identifier}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{35}
+\glossaryentry{MS?\glossaryentryfield{ms}{\glsnamefont{MS}}{Mobile Station}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{SIM?\glossaryentryfield{sim}{\glsnamefont{SIM}}{Subscriber Identity Module}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{BMI?\glossaryentryfield{bmi}{\glsnamefont{BMI}}{Bundesminiterium des Inneren}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{BKA?\glossaryentryfield{bka}{\glsnamefont{BKA}}{Bundeskriminalamt}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{BGS?\glossaryentryfield{bgs}{\glsnamefont{BGS}}{Bundesgrenzschutz}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{36}
+\glossaryentry{IMSI?\glossaryentryfield{imsi}{\glsnamefont{IMSI}}{International Mobile Subscriber Identification}{\relax }|setentrycounter{page}\glsnumberformat}{37}
diff --git a/Tex/Master/Master.aux b/Tex/Master/Master.aux
index cb7b86b..4ed3b44 100644
--- a/Tex/Master/Master.aux
+++ b/Tex/Master/Master.aux
@@ -15,6 +15,7 @@
\FN@pp@footnotehinttrue
\FN@pp@footnotehinttrue
\FN@pp@footnotehinttrue
+\FN@pp@footnotehinttrue
\citation{GSM2009}
\citation{GSM_history2011}
\citation{GSM_stats2011}
@@ -201,8 +202,8 @@
\citation{mueller}
\@writefile{toc}{\contentsline {subsubsection}{Attacks}{35}}
\newlabel{sec:attacks}{{2.4.1}{35}}
-\@writefile{toc}{\contentsline {paragraph}{\gls {ms} is in normal cell selection mode:}{35}}
-\@writefile{toc}{\contentsline {paragraph}{\gls {ms} is already connected to a network:}{35}}
+\@writefile{toc}{\contentsline {paragraph}{MS is in normal cell selection mode:}{35}}
+\@writefile{toc}{\contentsline {paragraph}{MS is already connected to a network:}{35}}
\citation{fox}
\citation{fox}
\citation{imsi_wiki}
diff --git a/Tex/Master/Master.log b/Tex/Master/Master.log
index 3b87f6a..a46f40c 100644
--- a/Tex/Master/Master.log
+++ b/Tex/Master/Master.log
@@ -1,40 +1,39 @@
-This is pdfTeX, Version 3.1415926-2.3-1.40.12 (MiKTeX 2.9 64-bit) (preloaded format=pdflatex 2012.1.30) 28 FEB 2012 12:21
+This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.1.7) 28 FEB 2012 12:27
entering extended mode
+ %&-line parsing enabled.
**Master.tex
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.tex
-LaTeX2e <2011/06/27>
-Babel <v3.8m> and hyphenation patterns for english, afrikaans, ancientgreek, ar
-abic, armenian, assamese, basque, bengali, bokmal, bulgarian, catalan, coptic,
-croatian, czech, danish, dutch, esperanto, estonian, farsi, finnish, french, ga
-lician, german, german-x-2009-06-19, greek, gujarati, hindi, hungarian, iceland
-ic, indonesian, interlingua, irish, italian, kannada, kurmanji, lao, latin, lat
-vian, lithuanian, malayalam, marathi, mongolian, mongolianlmc, monogreek, ngerm
-an, ngerman-x-2009-06-19, nynorsk, oriya, panjabi, pinyin, polish, portuguese,
-romanian, russian, sanskrit, serbian, slovak, slovenian, spanish, swedish, swis
-sgerman, tamil, telugu, turkish, turkmen, ukenglish, ukrainian, uppersorbian, u
-senglishmax, welsh, loaded.
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrbook.cls"
-Document Class: scrbook 2011/06/16 v3.09a KOMA-Script document class (book)
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrkbase.sty"
-Package: scrkbase 2011/06/16 v3.09a KOMA-Script package (KOMA-Script-dependent
+(./Master.tex
+LaTeX2e <2009/09/24>
+Babel <v3.8l> and hyphenation patterns for english, usenglishmax, dumylang, noh
+yphenation, farsi, arabic, croatian, bulgarian, ukrainian, russian, czech, slov
+ak, danish, dutch, finnish, french, basque, ngerman, german, german-x-2009-06-1
+9, ngerman-x-2009-06-19, ibycus, monogreek, greek, ancientgreek, hungarian, san
+skrit, italian, latin, latvian, lithuanian, mongolian2a, mongolian, bokmal, nyn
+orsk, romanian, irish, coptic, serbian, turkish, welsh, esperanto, uppersorbian
+, estonian, indonesian, interlingua, icelandic, kurmanji, slovenian, polish, po
+rtuguese, spanish, galician, catalan, swedish, ukenglish, pinyin, loaded.
+(/usr/share/texmf-texlive/tex/latex/koma-script/scrbook.cls
+Document Class: scrbook 2009/07/24 v3.04a KOMA-Script document class (book)
+(/usr/share/texmf-texlive/tex/latex/koma-script/scrkbase.sty
+Package: scrkbase 2009/07/24 v3.04a KOMA-Script package (KOMA-Script-dependent
basics and keyval usage)
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrbase.sty"
-Package: scrbase 2011/06/16 v3.09a KOMA-Script package (KOMA-Script-independent
+(/usr/share/texmf-texlive/tex/latex/koma-script/scrbase.sty
+Package: scrbase 2009/07/24 v3.04a KOMA-Script package (KOMA-Script-independent
basics and keyval usage)
-("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\keyval.sty"
+(/usr/share/texmf-texlive/tex/latex/graphics/keyval.sty
Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
\KV@toks@=\toks14
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrlfile.sty"
-Package: scrlfile 2011/03/09 v3.09 KOMA-Script package (loading files)
+(/usr/share/texmf-texlive/tex/latex/koma-script/scrlfile.sty
+Package: scrlfile 2009/03/25 v3.03 KOMA-Script package (loading files)
-Package scrlfile, 2011/03/09 v3.09 KOMA-Script package (loading files)
+Package scrlfile, 2009/03/25 v3.03 KOMA-Script package (loading files)
Copyright (C) Markus Kohm
-))) ("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\tocbasic.sty"
-Package: tocbasic 2011/05/30 v3.09a KOMA-Script package (handling toc-files)
+))) (/usr/share/texmf-texlive/tex/latex/koma-script/tocbasic.sty
+Package: tocbasic 2009/06/08 v3.03b KOMA-Script package (handling toc-files)
)
Package tocbasic Info: omitting babel extension for `toc'
(tocbasic) because of feature `nobabel' available
@@ -57,15 +56,15 @@ lain'.
Class scrbook Info: Switching compatibility level to `first'.
Class scrbook Info: File `scrsize11pt.clo' used to setup font sizes on input li
-ne 1348.
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrsize11pt.clo"
-File: scrsize11pt.clo 2011/06/16 v3.09a KOMA-Script font size class option (11p
+ne 1272.
+(/usr/share/texmf-texlive/tex/latex/koma-script/scrsize11pt.clo
+File: scrsize11pt.clo 2009/07/24 v3.04a KOMA-Script font size class option (11p
t)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\typearea.sty"
-Package: typearea 2011/06/16 v3.09a KOMA-Script package (type area)
+(/usr/share/texmf-texlive/tex/latex/koma-script/typearea.sty
+Package: typearea 2009/07/24 v3.04a KOMA-Script package (type area)
-Package typearea, 2011/06/16 v3.09a KOMA-Script package (type area)
+Package typearea, 2009/07/24 v3.04a KOMA-Script package (type area)
Copyright (C) Frank Neukam, 1992-1994
Copyright (C) Markus Kohm, 1994-
@@ -73,7 +72,7 @@ Package typearea, 2011/06/16 v3.09a KOMA-Script package (type area)
\ta@div=\count79
Package typearea Info: You've used standard option `a4paper'.
(typearea) This is correct!
-(typearea) Internally I'm using `paper=a4'.
+(typearea) Internaly I'm using `paper=a4'.
(typearea) If you'd like to set the option with \KOMAoptions,
(typearea) you'd have to use `paper=a4' there
(typearea) instead of `a4paper', too.
@@ -96,7 +95,7 @@ Package typearea Info: These are the values describing the layout:
(typearea) \topskip = 11.0pt
(typearea) \footskip = 47.60002pt
(typearea) \baselineskip = 13.6pt
-(typearea) on input line 1139.
+(typearea) on input line 1115.
)
\c@part=\count80
\c@chapter=\count81
@@ -112,82 +111,82 @@ Package typearea Info: These are the values describing the layout:
\c@table=\count88
\bibindent=\dimen102
)
-Package scrkbase Info: You've told me to extend the font selection of the
-(scrkbase) element `sectioning' that is an alias of element
-(scrkbase) `disposition' on input line 11.
- ("C:\Program Files\MiKTeX 2.9\tex\latex\eurosym\eurosym.sty"
+Class scrbook Info: You've told me to extend the font selection of the
+(scrbook) element `sectioning' that is an alias of element
+(scrbook) `disposition' on input line 11.
+ (./titlepage.sty
+Package: titlepage 2011/06/07 v0.2 KOMA presents the title page project
+
+
+LaTeX Warning: You have requested, on input line 34, version
+ `2011/06/07' of package scrbase,
+ but only version
+ `2009/07/24 v3.04a KOMA-Script package (KOMA-Script-independent
+basics and keyval usage)'
+ is available.
+
+\c@titlepage=\count89
+\titlebox=\box27
+) (/usr/share/texmf-texlive/tex/latex/eurosym/eurosym.sty
Package: eurosym 1998/08/06 v1.1 European currency symbol ``Euro''
-\@eurobox=\box27
+\@eurobox=\box28
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\appendix\appendix.sty"
+(/usr/share/texmf-texlive/tex/latex/appendix/appendix.sty
Package: appendix 2009/09/02 v1.2b extra appendix facilities
-\c@@pps=\count89
-\c@@ppsavesec=\count90
-\c@@ppsaveapp=\count91
+\c@@pps=\count90
+\c@@ppsavesec=\count91
+\c@@ppsaveapp=\count92
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\babel\babel.sty"
-Package: babel 2008/07/08 v3.8m The Babel package
+(/var/lib/texmf/tex/generic/babel/babel.sty
+Package: babel 2008/07/06 v3.8l The Babel package
-*************************************
-* Local config file bblopts.cfg used
-*
-("C:\Program Files\MiKTeX 2.9\tex\latex\00miktex\bblopts.cfg"
-File: bblopts.cfg 2006/07/31 v1.0 MiKTeX 'babel' configuration
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\babel\english.ldf"
+(/usr/share/texmf-texlive/tex/generic/babel/english.ldf
Language: english 2005/03/30 v3.3o English support from the babel system
-("C:\Program Files\MiKTeX 2.9\tex\generic\babel\babel.def"
-File: babel.def 2008/07/08 v3.8m Babel common definitions
-\babel@savecnt=\count92
+(/usr/share/texmf-texlive/tex/generic/babel/babel.def
+File: babel.def 2008/07/06 v3.8l Babel common definitions
+\babel@savecnt=\count93
\U@D=\dimen103
)
\l@canadian = a dialect from \language\l@american
\l@australian = a dialect from \language\l@british
\l@newzealand = a dialect from \language\l@british
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\base\inputenc.sty"
+(/usr/share/texmf-texlive/tex/latex/base/inputenc.sty
Package: inputenc 2008/03/30 v1.1d Input encoding file
\inpenc@prehook=\toks15
\inpenc@posthook=\toks16
-("C:\Program Files\MiKTeX 2.9\tex\latex\unicode\utf8x.def"
+(/usr/share/texmf-texlive/tex/latex/ucs/utf8x.def
File: utf8x.def 2004/10/17 UCS: Input encoding UTF-8
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\unicode\ucs.sty"
+(/usr/share/texmf-texlive/tex/latex/ucs/ucs.sty
Package: ucs 2004/10/17 UCS: Unicode input support
-("C:\Program Files\MiKTeX 2.9\tex\latex\unicode\data\uni-global.def"
+(/usr/share/texmf-texlive/tex/latex/ucs/data/uni-global.def
File: uni-global.def 2004/10/17 UCS: Unicode global data
)
-\uc@secondtry=\count93
+\uc@secondtry=\count94
\uc@combtoks=\toks17
\uc@combtoksb=\toks18
\uc@temptokena=\toks19
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\xcolor\xcolor.sty"
+(/usr/share/texmf/tex/latex/xcolor/xcolor.sty
Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK)
-("C:\Program Files\MiKTeX 2.9\tex\latex\00miktex\color.cfg"
+(/etc/texmf/tex/latex/config/color.cfg
File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive
)
Package xcolor Info: Driver file: pdftex.def on input line 225.
-("C:\Program Files\MiKTeX 2.9\tex\latex\pdftex-def\pdftex.def"
-File: pdftex.def 2011/05/27 v0.06d Graphics/color for pdfTeX
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\infwarerr.sty"
-Package: infwarerr 2010/04/08 v1.3 Providing info/warning/message (HO)
+(/usr/share/texmf-texlive/tex/latex/pdftex-def/pdftex.def
+File: pdftex.def 2010/03/12 v0.04p Graphics/color for pdfTeX
+\Gread@gobject=\count95
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\ltxcmds.sty"
-Package: ltxcmds 2011/04/18 v1.20 LaTeX kernel commands for general use (HO)
-)
-\Gread@gobject=\count94
-)
-("C:\Program Files\MiKTeX 2.9\tex\latex\colortbl\colortbl.sty"
+(/usr/share/texmf-texlive/tex/latex/colortbl/colortbl.sty
Package: colortbl 2001/02/13 v0.1j Color table columns (DPC)
-("C:\Program Files\MiKTeX 2.9\tex\latex\tools\array.sty"
+(/usr/share/texmf-texlive/tex/latex/tools/array.sty
Package: array 2008/09/09 v2.4c Tabular extension package (FMi)
\col@sep=\dimen104
\extrarowheight=\dimen105
@@ -198,7 +197,7 @@ Package: array 2008/09/09 v2.4c Tabular extension package (FMi)
\everycr=\toks21
\minrowclearance=\skip49
)
-\rownum=\count95
+\rownum=\count96
Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337.
Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1341.
Package xcolor Info: Model `RGB' extended on input line 1353.
@@ -209,10 +208,10 @@ Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358.
Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359.
Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360.
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\amsfonts\amssymb.sty"
+(/usr/share/texmf-texlive/tex/latex/amsfonts/amssymb.sty
Package: amssymb 2009/06/22 v3.00
-("C:\Program Files\MiKTeX 2.9\tex\latex\amsfonts\amsfonts.sty"
+(/usr/share/texmf-texlive/tex/latex/amsfonts/amsfonts.sty
Package: amsfonts 2009/06/22 v3.00 Basic AMSFonts support
\@emptytoks=\toks22
\symAMSa=\mathgroup4
@@ -220,50 +219,50 @@ Package: amsfonts 2009/06/22 v3.00 Basic AMSFonts support
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
(Font) U/euf/m/n --> U/euf/b/n on input line 96.
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\ams\math\amsmath.sty"
+(/usr/share/texmf-texlive/tex/latex/amsmath/amsmath.sty
Package: amsmath 2000/07/18 v2.13 AMS math features
\@mathmargin=\skip50
For additional information on amsmath, use the `?' option.
-("C:\Program Files\MiKTeX 2.9\tex\latex\ams\math\amstext.sty"
+(/usr/share/texmf-texlive/tex/latex/amsmath/amstext.sty
Package: amstext 2000/06/29 v2.01
-("C:\Program Files\MiKTeX 2.9\tex\latex\ams\math\amsgen.sty"
+(/usr/share/texmf-texlive/tex/latex/amsmath/amsgen.sty
File: amsgen.sty 1999/11/30 v2.0
\@emptytoks=\toks23
\ex@=\dimen106
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\ams\math\amsbsy.sty"
+(/usr/share/texmf-texlive/tex/latex/amsmath/amsbsy.sty
Package: amsbsy 1999/11/29 v1.2d
\pmbraise@=\dimen107
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\ams\math\amsopn.sty"
+(/usr/share/texmf-texlive/tex/latex/amsmath/amsopn.sty
Package: amsopn 1999/12/14 v2.01 operator names
)
-\inf@bad=\count96
+\inf@bad=\count97
LaTeX Info: Redefining \frac on input line 211.
-\uproot@=\count97
-\leftroot@=\count98
+\uproot@=\count98
+\leftroot@=\count99
LaTeX Info: Redefining \overline on input line 307.
-\classnum@=\count99
-\DOTSCASE@=\count100
+\classnum@=\count100
+\DOTSCASE@=\count101
LaTeX Info: Redefining \ldots on input line 379.
LaTeX Info: Redefining \dots on input line 382.
LaTeX Info: Redefining \cdots on input line 467.
-\Mathstrutbox@=\box28
-\strutbox@=\box29
+\Mathstrutbox@=\box29
+\strutbox@=\box30
\big@size=\dimen108
LaTeX Font Info: Redeclaring font encoding OML on input line 567.
LaTeX Font Info: Redeclaring font encoding OMS on input line 568.
-\macc@depth=\count101
-\c@MaxMatrixCols=\count102
+\macc@depth=\count102
+\c@MaxMatrixCols=\count103
\dotsspace@=\muskip10
-\c@parentequation=\count103
-\dspbrk@lvl=\count104
+\c@parentequation=\count104
+\dspbrk@lvl=\count105
\tag@help=\toks24
-\row@=\count105
-\column@=\count106
-\maxfields@=\count107
+\row@=\count106
+\column@=\count107
+\maxfields@=\count108
\andhelp@=\toks25
\eqnshift@=\dimen109
\alignsep@=\dimen110
@@ -278,121 +277,126 @@ LaTeX Font Info: Redeclaring font encoding OMS on input line 568.
LaTeX Info: Redefining \[ on input line 2666.
LaTeX Info: Redefining \] on input line 2667.
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\graphicx.sty"
+(/usr/share/texmf-texlive/tex/latex/graphics/graphicx.sty
Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
-("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\graphics.sty"
+(/usr/share/texmf-texlive/tex/latex/graphics/graphics.sty
Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR)
-("C:\Program Files\MiKTeX 2.9\tex\latex\graphics\trig.sty"
+(/usr/share/texmf-texlive/tex/latex/graphics/trig.sty
Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\00miktex\graphics.cfg"
-File: graphics.cfg 2007/01/18 v1.5 graphics configuration of teTeX/TeXLive
+(/etc/texmf/tex/latex/config/graphics.cfg
+File: graphics.cfg 2009/08/28 v1.8 graphics configuration of TeX Live
)
Package graphics Info: Driver file: pdftex.def on input line 91.
)
\Gin@req@height=\dimen115
\Gin@req@width=\dimen116
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\oberdiek\epstopdf.sty"
-Package: epstopdf 2010/02/09 v2.5 Conversion with epstopdf on the fly (HO)
-
-("C:\Program Files\MiKTeX 2.9\tex\latex\oberdiek\epstopdf-base.sty"
-Package: epstopdf-base 2010/02/09 v2.5 Base part for package epstopdf
+(/usr/share/texmf-texlive/tex/latex/oberdiek/epstopdf.sty
+Package: epstopdf 2009/10/17 v2.4 Conversion with epstopdf on the fly (HO)
-("C:\Program Files\MiKTeX 2.9\tex\latex\oberdiek\grfext.sty"
-Package: grfext 2010/08/19 v1.1 Managing graphics extensions (HO)
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\kvdefinekeys.sty"
-Package: kvdefinekeys 2011/04/07 v1.3 Defining keys (HO)
-))
-("C:\Program Files\MiKTeX 2.9\tex\latex\oberdiek\kvoptions.sty"
-Package: kvoptions 2010/12/23 v3.10 Keyval support for LaTeX options (HO)
+(/usr/share/texmf-texlive/tex/latex/oberdiek/epstopdf-base.sty
+Package: epstopdf-base 2009/10/17 v2.4 Base part for package epstopdf
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\kvsetkeys.sty"
-Package: kvsetkeys 2011/04/07 v1.13 Key value parser (HO)
+(/usr/share/texmf-texlive/tex/generic/oberdiek/infwarerr.sty
+Package: infwarerr 2007/09/09 v1.2 Providing info/warning/message (HO)
+)
+(/usr/share/texmf-texlive/tex/latex/oberdiek/grfext.sty
+Package: grfext 2007/09/30 v1.0 Managing graphics extensions (HO)
+)
+(/usr/share/texmf-texlive/tex/latex/oberdiek/kvoptions.sty
+Package: kvoptions 2009/08/13 v3.4 Keyval support for LaTeX options (HO)
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\etexcmds.sty"
-Package: etexcmds 2011/02/16 v1.5 Prefix for e-TeX command names (HO)
+(/usr/share/texmf-texlive/tex/generic/oberdiek/kvsetkeys.sty
+Package: kvsetkeys 2009/07/30 v1.5 Key value parser with default handler suppor
+t (HO)
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\ifluatex.sty"
-Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO)
-Package ifluatex Info: LuaTeX not detected.
-)
+(/usr/share/texmf-texlive/tex/generic/oberdiek/etexcmds.sty
+Package: etexcmds 2007/12/12 v1.2 Prefix for e-TeX command names (HO)
Package etexcmds Info: Could not find \expanded.
(etexcmds) That can mean that you are not using pdfTeX 1.50 or
(etexcmds) that some package has redefined \expanded.
(etexcmds) In the latter case, load this package earlier.
)))
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\pdftexcmds.sty"
-Package: pdftexcmds 2011/04/22 v0.16 Utilities of pdfTeX for LuaTeX (HO)
+(/usr/share/texmf-texlive/tex/generic/oberdiek/pdftexcmds.sty
+Package: pdftexcmds 2009/09/23 v0.6 LuaTeX support for pdfTeX utility functions
+ (HO)
-("C:\Program Files\MiKTeX 2.9\tex\generic\oberdiek\ifpdf.sty"
-Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO)
-Package ifpdf Info: pdfTeX in PDF mode is detected.
+(/usr/share/texmf-texlive/tex/generic/oberdiek/ifluatex.sty
+Package: ifluatex 2009/04/17 v1.2 Provides the ifluatex switch (HO)
+Package ifluatex Info: LuaTeX not detected.
+)
+(/usr/share/texmf-texlive/tex/generic/oberdiek/ltxcmds.sty
+Package: ltxcmds 2009/08/05 v1.0 Some LaTeX kernel commands for general use (HO
+)
)
Package pdftexcmds Info: LuaTeX not detected.
Package pdftexcmds Info: \pdf@primitive is available.
Package pdftexcmds Info: \pdf@ifprimitive is available.
-Package pdftexcmds Info: \pdfdraftmode found.
)
+
+Package epstopdf Warning: Shell escape feature is not enabled.
+
Package grfext Info: Graphics extension search list:
(grfext) [.png,.pdf,.jpg,.mps,.jpeg,.jbig2,.jb2,.PNG,.PDF,.JPG,.JPE
G,.JBIG2,.JB2,.eps]
-(grfext) \AppendGraphicsExtensions on input line 452.
-))
-("C:\Program Files\MiKTeX 2.9\tex\latex\listings\listings.sty"
-\lst@mode=\count108
-\lst@gtempboxa=\box30
+(grfext) \AppendGraphicsExtensions on input line 433.
+(/usr/share/texmf-texlive/tex/latex/latexconfig/epstopdf-sys.cfg
+File: epstopdf-sys.cfg 2009/10/26 v1.1 Configuration of epstopdf for TeX Live
+)))
+(/usr/share/texmf-texlive/tex/latex/listings/listings.sty
+\lst@mode=\count109
+\lst@gtempboxa=\box31
\lst@token=\toks28
-\lst@length=\count109
+\lst@length=\count110
\lst@currlwidth=\dimen117
-\lst@column=\count110
-\lst@pos=\count111
+\lst@column=\count111
+\lst@pos=\count112
\lst@lostspace=\dimen118
\lst@width=\dimen119
-\lst@newlines=\count112
-\lst@lineno=\count113
+\lst@newlines=\count113
+\lst@lineno=\count114
\lst@maxwidth=\dimen120
-("C:\Program Files\MiKTeX 2.9\tex\latex\listings\lstmisc.sty"
+(/usr/share/texmf-texlive/tex/latex/listings/lstmisc.sty
File: lstmisc.sty 2007/02/22 1.4 (Carsten Heinz)
-\c@lstnumber=\count114
-\lst@skipnumbers=\count115
-\lst@framebox=\box31
+\c@lstnumber=\count115
+\lst@skipnumbers=\count116
+\lst@framebox=\box32
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\listings\listings.cfg"
+(/usr/share/texmf-texlive/tex/latex/listings/listings.cfg
File: listings.cfg 2007/02/22 1.4 listings configuration
))
Package: listings 2007/02/22 1.4 (Carsten Heinz)
-("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\times.sty"
+(/usr/share/texmf-texlive/tex/latex/psnfss/times.sty
Package: times 2005/04/12 PSNFSS-v9.2a (SPQR)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\helvet.sty"
+(/usr/share/texmf-texlive/tex/latex/psnfss/helvet.sty
Package: helvet 2005/04/12 PSNFSS-v9.2a (WaS)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\courier.sty"
+(/usr/share/texmf-texlive/tex/latex/psnfss/courier.sty
Package: courier 2005/04/12 PSNFSS-v9.2a (WaS)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\esvect\esvect.sty"
+(/usr/share/texmf-texlive/tex/latex/esvect/esvect.sty
Package: esvect
\symesvector=\mathgroup6
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\base\fontenc.sty"
+(/usr/share/texmf-texlive/tex/latex/base/fontenc.sty
Package: fontenc 2005/09/27 v1.99g Standard LaTeX package
-("C:\Program Files\MiKTeX 2.9\tex\latex\base\t1enc.def"
+(/usr/share/texmf-texlive/tex/latex/base/t1enc.def
File: t1enc.def 2005/09/27 v1.99g Standard LaTeX file
LaTeX Font Info: Redeclaring font encoding T1 on input line 43.
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\footmisc\footmisc.sty"
-Package: footmisc 2011/06/06 v5.5b a miscellany of footnote facilities
+(/usr/share/texmf-texlive/tex/latex/footmisc/footmisc.sty
+Package: footmisc 2009/09/15 v5.5a a miscellany of footnote facilities
\FN@temptoken=\toks29
\footnotemargin=\dimen121
-\c@pp@next@reset=\count116
-\c@@fnserial=\count117
+\c@pp@next@reset=\count117
+\c@@fnserial=\count118
Package footmisc Info: Declaring symbol style bringhurst on input line 855.
Package footmisc Info: Declaring symbol style chicago on input line 863.
Package footmisc Info: Declaring symbol style wiley on input line 872.
@@ -402,106 +406,90 @@ Package footmisc Info: Declaring symbol style lamport* on input line 903.
Package footmisc Info: Declaring symbol style lamport*-robust on input line 924
.
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\listing\listing.sty"
+(/usr/share/texmf-texlive/tex/latex/ltxmisc/listing.sty
Package: listing 1999/05/25
Package `listing', V1.2, <1999/05/25>
-\c@listing=\count118
-) (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\multido.sty
+\c@listing=\count119
+) (./multido.sty
Package: multido 2004/05/17 package wrapper for PSTricks `multido.tex', (HV/RN)
-
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\multido.tex
- v1.41, 2004/05/18 <tvz>
-\multido@count=\count119
-\multidocount=\count120
+ (./multido.tex v1.41, 2004/05/18 <tvz>
+\multido@count=\count120
+\multidocount=\count121
\multido@stuff=\toks30
)
File: multido.tex 2004/05/18 v1.41 `multido' (tvz)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\base\glossaries.sty"
-Package: glossaries 2011/04/12 v3.01 (NLCT)
+(/usr/share/texmf-texlive/tex/latex/glossaries/base/glossaries.sty
+Package: glossaries 2009/09/23 v2.03 (NLCT)
-("C:\Program Files\MiKTeX 2.9\tex\latex\base\ifthen.sty"
+(/usr/share/texmf-texlive/tex/latex/base/ifthen.sty
Package: ifthen 2001/05/26 v1.1c Standard LaTeX ifthen package (DPC)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\xkeyval\xkeyval.sty"
+(/usr/share/texmf-texlive/tex/latex/xkeyval/xkeyval.sty
Package: xkeyval 2008/08/13 v2.6a package option processing (HA)
-("C:\Program Files\MiKTeX 2.9\tex\generic\xkeyval\xkeyval.tex"
+(/usr/share/texmf-texlive/tex/generic/xkeyval/xkeyval.tex
\XKV@toks=\toks31
\XKV@tempa@toks=\toks32
-\XKV@depth=\count121
+\XKV@depth=\count122
File: xkeyval.tex 2008/08/13 v2.6a key=value parser (HA)
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\base\mfirstuc.sty"
-Package: mfirstuc 2011/04/02 v1.05 (NLCT)
-\@glsmfirst=\toks33
-\@glsmrest=\toks34
+(/usr/share/texmf-texlive/tex/latex/glossaries/base/mfirstuc.sty
+Package: mfirstuc 2008/12/22 v1.03 (NLCT)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\xfor\xfor.sty"
+(/usr/share/texmf-texlive/tex/latex/xfor/xfor.sty
Package: xfor 2009/02/05 v1.05 (NLCT)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\etoolbox\etoolbox.sty"
-Package: etoolbox 2011/01/03 v2.1 e-TeX tools for LaTeX
-
-("C:\Program Files\MiKTeX 2.9\tex\latex\misc\etex.sty"
-Package: etex 1998/03/26 v2.0 eTeX basic definition package (PEB)
-\et@xins=\count122
-)
-\etb@tempcnta=\count123
-)
-("C:\Program Files\MiKTeX 2.9\tex\latex\beamer\base\translator\translator.sty"
+(/usr/share/texmf/tex/latex/beamer/base/translator/translator.sty
Package: translator 2010/06/12 ver 1.10
-("C:\Program Files\MiKTeX 2.9\tex\latex\beamer\base\translator\translator-langu
-age-mappings.tex"))
-\gls@level=\count124
-\@gls@tmpb=\toks35
+(/usr/share/texmf/tex/latex/beamer/base/translator/translator-language-mappings
+.tex))
+\gls@level=\count123
+\@gls@tmpb=\toks33
\gls@tmplen=\skip53
-\glswrite=\write3
-\glskeylisttok=\toks36
-\glslabeltok=\toks37
-\glsshorttok=\toks38
-\glslongtok=\toks39
-
-("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\styles\glossary-hypernav.sty
-"
+\istfile=\write3
+
+(/usr/share/texmf-texlive/tex/latex/glossaries/styles/glossary-hypernav.sty
Package: glossary-hypernav 2007/07/04 v1.01 (NLCT)
-) ("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\styles\glossary-list.sty"
-Package: glossary-list 2011/03/28 v3.0 (NLCT)
+)
+(/usr/share/texmf-texlive/tex/latex/glossaries/styles/glossary-list.sty
+Package: glossary-list 2009/05/30 v2.01 (NLCT)
\glslistdottedwidth=\skip54
-) ("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\styles\glossary-long.sty"
-Package: glossary-long 2011/03/28 v3.0 (NLCT)
+)
+(/usr/share/texmf-texlive/tex/latex/glossaries/styles/glossary-long.sty
+Package: glossary-long 2009/05/30 v2.01 (NLCT)
-("C:\Program Files\MiKTeX 2.9\tex\latex\tools\longtable.sty"
+(/usr/share/texmf-texlive/tex/latex/tools/longtable.sty
Package: longtable 2004/02/01 v4.11 Multi-page Table package (DPC)
\LTleft=\skip55
\LTright=\skip56
\LTpre=\skip57
\LTpost=\skip58
-\LTchunksize=\count125
+\LTchunksize=\count124
\LTcapwidth=\dimen122
-\LT@head=\box32
-\LT@firsthead=\box33
-\LT@foot=\box34
-\LT@lastfoot=\box35
-\LT@cols=\count126
-\LT@rows=\count127
-\c@LT@tables=\count128
-\c@LT@chunks=\count129
-\LT@p@ftn=\toks40
+\LT@head=\box33
+\LT@firsthead=\box34
+\LT@foot=\box35
+\LT@lastfoot=\box36
+\LT@cols=\count125
+\LT@rows=\count126
+\c@LT@tables=\count127
+\c@LT@chunks=\count128
+\LT@p@ftn=\toks34
)
Class scrbook Info: longtable captions redefined on input line 43.
\glsdescwidth=\skip59
\glspagelistwidth=\skip60
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\styles\glossary-super.sty"
-Package: glossary-super 2011/03/28 v3.0 (NLCT)
+(/usr/share/texmf-texlive/tex/latex/glossaries/styles/glossary-super.sty
+Package: glossary-super 2009/05/30 v2.01 (NLCT)
-("C:\Program Files\MiKTeX 2.9\tex\latex\supertabular\supertabular.sty"
+(/usr/share/texmf-texlive/tex/latex/supertabular/supertabular.sty
Package: supertabular 2004/02/20 v4.1e the supertabular environment
-\c@tracingst=\count130
+\c@tracingst=\count129
\ST@wd=\dimen123
\ST@rightskip=\skip61
\ST@leftskip=\skip62
@@ -516,512 +504,426 @@ Package: supertabular 2004/02/20 v4.1e the supertabular environment
\ST@prevht=\dimen131
\ST@toadd=\dimen132
\ST@dimen=\dimen133
-\ST@pbox=\box36
+\ST@pbox=\box37
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\styles\glossary-tree.sty"
-Package: glossary-tree 2011/03/28 v3.0 (NLCT)
+(/usr/share/texmf-texlive/tex/latex/glossaries/styles/glossary-tree.sty
+Package: glossary-tree 2009/01/14 v1.01 (NLCT)
\glstreeindent=\skip64
))
-("C:\Program Files\MiKTeX 2.9\tex\latex\pstricks\pstricks.sty"
-Package: pstricks 2011/10/31 v0.52 LaTeX wrapper for `PSTricks' (RN,HV)
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\pstricks\base\pstricks.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\xkeyval\pst-xkey.tex"
-File: pst-xkey.tex 2005/11/25 v1.6 PSTricks specialization of xkeyval (HA)
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pstricks\base\pst-fp.tex"
-`pst-fp' v0.05, 2010/01/17 (hv)
-\pstFP@xs=\count131
-\pstFP@xia=\count132
-\pstFP@xib=\count133
-\pstFP@xfa=\count134
-\pstFP@xfb=\count135
-\pstFP@rega=\count136
-\pstFP@regb=\count137
-\pstFP@regs=\count138
-\pstFP@times=\count139
-)
-\psLoopIndex=\count140
-
-`PSTricks' v2.23 <2011/09/04> (tvz)
+(/usr/share/texmf-texlive/tex/latex/pstricks/pstricks.sty
+Package: pstricks 2008/11/26 v0.40 LaTeX wrapper for `PSTricks' (RN,HV)
+
+(/usr/share/texmf-texlive/tex/generic/pstricks/pstricks.tex
+`PSTricks' v1.29 <2009/05/19> (tvz)
\pst@dima=\dimen134
\pst@dimb=\dimen135
\pst@dimc=\dimen136
\pst@dimd=\dimen137
\pst@dimg=\dimen138
\pst@dimh=\dimen139
-\pst@dimm=\dimen140
-\pst@dimn=\dimen141
-\pst@dimo=\dimen142
-\pst@dimp=\dimen143
-\pst@hbox=\box37
-\pst@ibox=\box38
+\pst@hbox=\box38
\pst@boxg=\box39
-\pst@cnta=\count141
-\pst@cntb=\count142
-\pst@cntc=\count143
-\pst@cntd=\count144
-\pst@cntg=\count145
-\pst@cnth=\count146
-\pst@cntm=\count147
-\pst@cntn=\count148
-\pst@cnto=\count149
-\pst@cntp=\count150
-\@zero=\count151
-\pst@toks=\toks41
-("C:\Program Files\MiKTeX 2.9\tex\generic\pstricks\base\pstricks.con")
-\psunit=\dimen144
-\psxunit=\dimen145
-\psyunit=\dimen146
-\pst@C@@rType=\count152
-\pslinewidth=\dimen147
-\psk@startLW=\dimen148
-\psk@endLW=\dimen149
-\pst@customdefs=\toks42
-\pslinearc=\dimen150
-\pst@symbolStep=\dimen151
-\pst@symbolWidth=\dimen152
-\everypsbox=\toks43
-\psframesep=\dimen153
-\pslabelsep=\dimen154
-\pst@shift=\dimen155
+\pst@cnta=\count130
+\pst@cntb=\count131
+\pst@cntc=\count132
+\pst@cntd=\count133
+\pst@cntg=\count134
+\pst@cnth=\count135
+\pst@toks=\toks35
+(/usr/share/texmf-texlive/tex/generic/pstricks/pstricks.con)
+\psunit=\dimen140
+\psxunit=\dimen141
+\psyunit=\dimen142
+\pslinewidth=\dimen143
+\pst@customdefs=\toks36
+\pslinearc=\dimen144
+\everypsbox=\toks37
+\psframesep=\dimen145
+\pslabelsep=\dimen146
+\pst@shift=\dimen147
\theoverlaybox=\box40
)
-File: pstricks.tex 2011/09/04 v2.23 `PSTricks' (tvz,hv)
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\pstricks\base\pst-fp.tex")
-File: pst-fp.tex 2011/09/04 v2.23 `PST-fp' (hv)
+File: pstricks.tex 2009/05/19 v1.29 `PSTricks' (tvz,hv)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\lipsum\lipsum.sty"
-Package: lipsum 2011/04/14 v1.2 150 paragraphs of Lorem Ipsum dummy text
-\c@lips@count=\count153
+(/usr/share/texmf-texlive/tex/latex/lipsum/lipsum.sty
+Package: lipsum 2005/01/26 v1.0 150 paragraphs of Lorem Ipsum dummy text
+File: lipsum.dtx 2005/01/26 v1.0 150 paragraphs of Lorem Ipsum dummy text
+\c@lips@count=\count136
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgfplots\pgfplots.sty"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplots.revision.tex")
-Package: pgfplots 2011/12/29 v1.5.1 (git show 1.5.1-4-g53e640f )
+(/usr/share/texmf-texlive/tex/latex/pgfplots/pgfplots.sty
+Package: pgfplots 2009/02/14 Version 1.2.2
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\frontendlayer\tikz.sty"
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\basiclayer\pgf.sty"
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\utilities\pgfrcs.sty"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgfutil-common.tex"
-\pgfutil@everybye=\toks44
+(/usr/share/texmf/tex/latex/pgf/frontendlayer/tikz.sty
+(/usr/share/texmf/tex/latex/pgf/basiclayer/pgf.sty
+(/usr/share/texmf/tex/latex/pgf/utilities/pgfrcs.sty
+(/usr/share/texmf/tex/generic/pgf/utilities/pgfutil-common.tex
+\pgfutil@everybye=\toks38
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgfutil-latex.def"
+(/usr/share/texmf/tex/generic/pgf/utilities/pgfutil-latex.def
\pgfutil@abb=\box41
-("C:\Program Files\MiKTeX 2.9\tex\latex\ms\everyshi.sty"
+(/usr/share/texmf-texlive/tex/latex/ms/everyshi.sty
Package: everyshi 2001/05/15 v3.00 EveryShipout Package (MS)
))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgfrcs.code.tex"
+(/usr/share/texmf/tex/generic/pgf/utilities/pgfrcs.code.tex
Package: pgfrcs 2010/10/25 v2.10 (rcs-revision 1.24)
))
Package: pgf 2008/01/15 v2.10 (rcs-revision 1.12)
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\basiclayer\pgfcore.sty"
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\systemlayer\pgfsys.sty"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\systemlayer\pgfsys.code.tex"
+(/usr/share/texmf/tex/latex/pgf/basiclayer/pgfcore.sty
+(/usr/share/texmf/tex/latex/pgf/systemlayer/pgfsys.sty
+(/usr/share/texmf/tex/generic/pgf/systemlayer/pgfsys.code.tex
Package: pgfsys 2010/06/30 v2.10 (rcs-revision 1.37)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgfkeys.code.tex"
-\pgfkeys@pathtoks=\toks45
-\pgfkeys@temptoks=\toks46
+(/usr/share/texmf/tex/generic/pgf/utilities/pgfkeys.code.tex
+\pgfkeys@pathtoks=\toks39
+\pgfkeys@temptoks=\toks40
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgfkeysfiltered.code.te
-x"
-\pgfkeys@tmptoks=\toks47
+(/usr/share/texmf/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex
+\pgfkeys@tmptoks=\toks41
))
-\pgf@x=\dimen156
-\pgf@y=\dimen157
-\pgf@xa=\dimen158
-\pgf@ya=\dimen159
-\pgf@xb=\dimen160
-\pgf@yb=\dimen161
-\pgf@xc=\dimen162
-\pgf@yc=\dimen163
+\pgf@x=\dimen148
+\pgf@y=\dimen149
+\pgf@xa=\dimen150
+\pgf@ya=\dimen151
+\pgf@xb=\dimen152
+\pgf@yb=\dimen153
+\pgf@xc=\dimen154
+\pgf@yc=\dimen155
\w@pgf@writea=\write4
\r@pgf@reada=\read1
-\c@pgf@counta=\count154
-\c@pgf@countb=\count155
-\c@pgf@countc=\count156
-\c@pgf@countd=\count157
- ("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\systemlayer\pgf.cfg"
+\c@pgf@counta=\count137
+\c@pgf@countb=\count138
+\c@pgf@countc=\count139
+\c@pgf@countd=\count140
+
+(/usr/share/texmf/tex/generic/pgf/systemlayer/pgf.cfg
File: pgf.cfg 2008/05/14 (rcs-revision 1.7)
)
Package pgfsys Info: Driver file for pgf: pgfsys-pdftex.def on input line 900.
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\systemlayer\pgfsys-pdftex.def"
+(/usr/share/texmf/tex/generic/pgf/systemlayer/pgfsys-pdftex.def
File: pgfsys-pdftex.def 2009/05/22 (rcs-revision 1.26)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\systemlayer\pgfsys-common-pdf.def
-"
+(/usr/share/texmf/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def
File: pgfsys-common-pdf.def 2008/05/19 (rcs-revision 1.10)
)))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\systemlayer\pgfsyssoftpath.code.t
-ex"
+(/usr/share/texmf/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex
File: pgfsyssoftpath.code.tex 2008/07/18 (rcs-revision 1.7)
-\pgfsyssoftpath@smallbuffer@items=\count158
-\pgfsyssoftpath@bigbuffer@items=\count159
+\pgfsyssoftpath@smallbuffer@items=\count141
+\pgfsyssoftpath@bigbuffer@items=\count142
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\systemlayer\pgfsysprotocol.code.t
-ex"
+(/usr/share/texmf/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex
File: pgfsysprotocol.code.tex 2006/10/16 (rcs-revision 1.4)
-)) ("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcore.code.tex"
+))
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcore.code.tex
Package: pgfcore 2010/04/11 v2.10 (rcs-revision 1.7)
- ("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmath.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathcalc.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathutil.code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathparser.code.tex"
-\pgfmath@dimen=\dimen164
-\pgfmath@count=\count160
+
+(/usr/share/texmf/tex/generic/pgf/math/pgfmath.code.tex
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathcalc.code.tex
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathutil.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathparser.code.tex
+\pgfmath@dimen=\dimen156
+\pgfmath@count=\count143
\pgfmath@box=\box42
-\pgfmath@toks=\toks48
-\pgfmath@stack@operand=\toks49
-\pgfmath@stack@operation=\toks50
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.basic.code.
-tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.trigonometr
-ic.code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.random.code
-.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.comparison.
-code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.base.code.t
-ex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.round.code.
-tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfunctions.misc.code.t
-ex"))) ("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\math\pgfmathfloat.code.tex
-"
-\c@pgfmathroundto@lastzeros=\count161
+\pgfmath@toks=\toks42
+\pgfmath@stack@operand=\toks43
+\pgfmath@stack@operation=\toks44
+)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.code.tex
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.random.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.comparison.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.base.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.round.code.tex)
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex)))
+(/usr/share/texmf/tex/generic/pgf/math/pgfmathfloat.code.tex
+\c@pgfmathroundto@lastzeros=\count144
))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorepoints.code.tex
-"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex
File: pgfcorepoints.code.tex 2010/04/09 (rcs-revision 1.20)
-\pgf@picminx=\dimen165
-\pgf@picmaxx=\dimen166
-\pgf@picminy=\dimen167
-\pgf@picmaxy=\dimen168
-\pgf@pathminx=\dimen169
-\pgf@pathmaxx=\dimen170
-\pgf@pathminy=\dimen171
-\pgf@pathmaxy=\dimen172
-\pgf@xx=\dimen173
-\pgf@xy=\dimen174
-\pgf@yx=\dimen175
-\pgf@yy=\dimen176
-\pgf@zx=\dimen177
-\pgf@zy=\dimen178
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorepathconstruct.c
-ode.tex"
+\pgf@picminx=\dimen157
+\pgf@picmaxx=\dimen158
+\pgf@picminy=\dimen159
+\pgf@picmaxy=\dimen160
+\pgf@pathminx=\dimen161
+\pgf@pathmaxx=\dimen162
+\pgf@pathminy=\dimen163
+\pgf@pathmaxy=\dimen164
+\pgf@xx=\dimen165
+\pgf@xy=\dimen166
+\pgf@yx=\dimen167
+\pgf@yy=\dimen168
+\pgf@zx=\dimen169
+\pgf@zy=\dimen170
+)
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex
File: pgfcorepathconstruct.code.tex 2010/08/03 (rcs-revision 1.24)
-\pgf@path@lastx=\dimen179
-\pgf@path@lasty=\dimen180
+\pgf@path@lastx=\dimen171
+\pgf@path@lasty=\dimen172
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorepathusage.code.
-tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex
File: pgfcorepathusage.code.tex 2008/04/22 (rcs-revision 1.12)
-\pgf@shorten@end@additional=\dimen181
-\pgf@shorten@start@additional=\dimen182
+\pgf@shorten@end@additional=\dimen173
+\pgf@shorten@start@additional=\dimen174
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorescopes.code.tex
-"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex
File: pgfcorescopes.code.tex 2010/09/08 (rcs-revision 1.34)
\pgfpic=\box43
\pgf@hbox=\box44
\pgf@layerbox@main=\box45
-\pgf@picture@serial@count=\count162
+\pgf@picture@serial@count=\count145
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoregraphicstate.co
-de.tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex
File: pgfcoregraphicstate.code.tex 2008/04/22 (rcs-revision 1.9)
-\pgflinewidth=\dimen183
+\pgflinewidth=\dimen175
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoretransformations
-.code.tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex
File: pgfcoretransformations.code.tex 2009/06/10 (rcs-revision 1.11)
-\pgf@pt@x=\dimen184
-\pgf@pt@y=\dimen185
-\pgf@pt@temp=\dimen186
+\pgf@pt@x=\dimen176
+\pgf@pt@y=\dimen177
+\pgf@pt@temp=\dimen178
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorequick.code.tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorequick.code.tex
File: pgfcorequick.code.tex 2008/10/09 (rcs-revision 1.3)
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoreobjects.code.te
-x"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex
File: pgfcoreobjects.code.tex 2006/10/11 (rcs-revision 1.2)
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorepathprocessing.
-code.tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex
File: pgfcorepathprocessing.code.tex 2008/10/09 (rcs-revision 1.8)
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorearrows.code.tex
-"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex
File: pgfcorearrows.code.tex 2008/04/23 (rcs-revision 1.11)
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoreshade.code.tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex
File: pgfcoreshade.code.tex 2008/11/23 (rcs-revision 1.13)
-\pgf@max=\dimen187
-\pgf@sys@shading@range@num=\count163
-) ("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoreimage.code.te
-x"
+\pgf@max=\dimen179
+\pgf@sys@shading@range@num=\count146
+)
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex
File: pgfcoreimage.code.tex 2010/03/25 (rcs-revision 1.16)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoreexternal.code.t
-ex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex
File: pgfcoreexternal.code.tex 2010/09/01 (rcs-revision 1.17)
\pgfexternal@startupbox=\box46
))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorelayers.code.tex
-"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex
File: pgfcorelayers.code.tex 2010/08/27 (rcs-revision 1.2)
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcoretransparency.co
-de.tex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex
File: pgfcoretransparency.code.tex 2008/01/17 (rcs-revision 1.2)
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\basiclayer\pgfcorepatterns.code.t
-ex"
+(/usr/share/texmf/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex
File: pgfcorepatterns.code.tex 2009/07/02 (rcs-revision 1.3)
)))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\modules\pgfmoduleshapes.code.tex"
+(/usr/share/texmf/tex/generic/pgf/modules/pgfmoduleshapes.code.tex
File: pgfmoduleshapes.code.tex 2010/09/09 (rcs-revision 1.13)
\pgfnodeparttextbox=\box47
-) ("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\modules\pgfmoduleplot.code.tex"
+)
+(/usr/share/texmf/tex/generic/pgf/modules/pgfmoduleplot.code.tex
File: pgfmoduleplot.code.tex 2010/10/22 (rcs-revision 1.8)
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\compatibility\pgfcomp-version-0-65.
-sty"
+(/usr/share/texmf/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty
Package: pgfcomp-version-0-65 2007/07/03 v2.10 (rcs-revision 1.7)
-\pgf@nodesepstart=\dimen188
-\pgf@nodesepend=\dimen189
+\pgf@nodesepstart=\dimen180
+\pgf@nodesepend=\dimen181
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\compatibility\pgfcomp-version-1-18.
-sty"
+(/usr/share/texmf/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty
Package: pgfcomp-version-1-18 2007/07/23 v2.10 (rcs-revision 1.1)
-)) ("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\utilities\pgffor.sty"
-("C:\Program Files\MiKTeX 2.9\tex\latex\pgf\utilities\pgfkeys.sty"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgfkeys.code.tex"))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\utilities\pgffor.code.tex"
+))
+(/usr/share/texmf/tex/latex/pgf/utilities/pgffor.sty
+(/usr/share/texmf/tex/latex/pgf/utilities/pgfkeys.sty
+(/usr/share/texmf/tex/generic/pgf/utilities/pgfkeys.code.tex))
+(/usr/share/texmf/tex/generic/pgf/utilities/pgffor.code.tex
Package: pgffor 2010/03/23 v2.10 (rcs-revision 1.18)
-\pgffor@iter=\dimen190
-\pgffor@skip=\dimen191
-\pgffor@stack=\toks51
-\pgffor@toks=\toks52
+\pgffor@iter=\dimen182
+\pgffor@skip=\dimen183
+\pgffor@stack=\toks45
+\pgffor@toks=\toks46
))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\frontendlayer\tikz\tikz.code.tex"
+(/usr/share/texmf/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex
Package: tikz 2010/10/13 v2.10 (rcs-revision 1.76)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\libraries\pgflibraryplothandlers.
-code.tex"
+(/usr/share/texmf/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex
File: pgflibraryplothandlers.code.tex 2010/05/31 v2.10 (rcs-revision 1.15)
-\pgf@plot@mark@count=\count164
-\pgfplotmarksize=\dimen192
-)
-\tikz@lastx=\dimen193
-\tikz@lasty=\dimen194
-\tikz@lastxsaved=\dimen195
-\tikz@lastysaved=\dimen196
-\tikzleveldistance=\dimen197
-\tikzsiblingdistance=\dimen198
+\pgf@plot@mark@count=\count147
+\pgfplotmarksize=\dimen184
+)
+\tikz@lastx=\dimen185
+\tikz@lasty=\dimen186
+\tikz@lastxsaved=\dimen187
+\tikz@lastysaved=\dimen188
+\tikzleveldistance=\dimen189
+\tikzsiblingdistance=\dimen190
\tikz@figbox=\box48
\tikz@tempbox=\box49
-\tikztreelevel=\count165
-\tikznumberofchildren=\count166
-\tikznumberofcurrentchild=\count167
-\tikz@fig@count=\count168
+\tikztreelevel=\count148
+\tikznumberofchildren=\count149
+\tikznumberofcurrentchild=\count150
+\tikz@fig@count=\count151
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\modules\pgfmodulematrix.code.tex"
+(/usr/share/texmf/tex/generic/pgf/modules/pgfmodulematrix.code.tex
File: pgfmodulematrix.code.tex 2010/08/24 (rcs-revision 1.4)
-\pgfmatrixcurrentrow=\count169
-\pgfmatrixcurrentcolumn=\count170
-\pgf@matrix@numberofcolumns=\count171
+\pgfmatrixcurrentrow=\count152
+\pgfmatrixcurrentcolumn=\count153
+\pgf@matrix@numberofcolumns=\count154
)
-\tikz@expandcount=\count172
+\tikz@expandcount=\count155
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\frontendlayer\tikz\libraries\tikz
-librarytopaths.code.tex"
+(/usr/share/texmf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarytopat
+hs.code.tex
File: tikzlibrarytopaths.code.tex 2008/06/17 v2.10 (rcs-revision 1.2)
-)))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplots.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplotscore.code.tex"
-\t@pgfplots@toka=\toks53
-\t@pgfplots@tokb=\toks54
-\t@pgfplots@tokc=\toks55
-\pgfplots@tmpa=\dimen199
-\c@pgfplots@coordindex=\count173
-\c@pgfplots@scanlineindex=\count174
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\sys\pgfplotssysgeneric.code.
-tex"))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\libs\pgfplotslibrary.code.te
-x")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_loader.code.tex"
+))) (/usr/share/texmf-texlive/tex/generic/pgfplots/pgfplots.code.tex (/usr/shar
+e/texmf-texlive/tex/generic/pgfplots/pgfplotscore.code.tex
+\t@pgfplots@toka=\toks47
+\t@pgfplots@tokb=\toks48
+\t@pgfplots@tokc=\toks49
+\pgfplots@tmpa=\dimen191
+)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsup
+p_loader.code.tex
Package pgfplots: loading complementary code for your PGF version...
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_misc.code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_pgfkeys.code.tex"
-\pgfkeys@pathtoks=\toks56
-\pgfkeys@temptoks=\toks57
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_pgfkeysfiltered.code.tex"
-\pgfkeys@tmptoks=\toks58
-))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_pgfmathfloat.code.tex"
-\c@pgfmathroundto@lastzeros=\count175
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_pgflibraryplothandlers.code.tex"
-File: pgflibraryplothandlers.code.tex 2011/12/28 v2.10 (rcs-revision 1.16)
-\pgf@plot@mark@count=\count176
-\pgfplotmarksize=\dimen200
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\oldpgfcompatib\pgfplotsoldpg
-fsupp_pgflibraryfpu.code.tex"))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\util\pgfplotsutil.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\liststructure\pgfplotslistst
-ructure.code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\liststructure\pgfplotslistst
-ructureext.code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\liststructure\pgfplotsarray.
-code.tex"
-\c@pgfplotsarray@tmp=\count177
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\liststructure\pgfplotsmatrix
-.code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\numtable\pgfplotstableshared
-.code.tex"
-\c@pgfplotstable@counta=\count178
-\t@pgfplotstable@a=\toks59
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\liststructure\pgfplotsdeque.
-code.tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\util\pgfplotsbinary.code.tex
-")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\util\pgfplotsutil.verb.code.
-tex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\libs\pgflibrarypgfplots.surf
-shading.code.tex"
-\c@pgfplotslibrarysurf@no=\count179
-
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\sys\pgflibrarypgfplots.surfs
-hading.pgfsys-pdftex.def")))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\util\pgfplotscolormap.code.t
-ex")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplotsstackedplots.code.te
-x")
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplotsplothandlers.code.te
-x"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplotsmeshplothandler.code
-.tex"))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplotscoordprocessing.code
-.tex") ("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplotsticks.code.te
-x") ("C:\Program Files\MiKTeX 2.9\tex\generic\pgfplots\pgfplots.paths.code.tex"
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\frontendlayer\tikz\libraries\tikz
-librarydecorations.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\modules\pgfmoduledecorations.code
-.tex"
-\pgfdecoratedcompleteddistance=\dimen201
-\pgfdecoratedremainingdistance=\dimen202
-\pgfdecoratedinputsegmentcompleteddistance=\dimen203
-\pgfdecoratedinputsegmentremainingdistance=\dimen204
-\pgf@decorate@distancetomove=\dimen205
-\pgf@decorate@repeatstate=\count180
-\pgfdecorationsegmentamplitude=\dimen206
-\pgfdecorationsegmentlength=\dimen207
+(/usr/share/texmf-texlive/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsup
+p_misc.code.tex)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsup
+p_pgfkeysfiltered.code.tex
+\pgfkeys@tmptoks=\toks50
+)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsup
+p_pgfmathfloat.code.tex
+\c@pgfmathroundto@lastzeros=\count156
+)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/oldpgfcompatib/pgfplotsoldpgfsup
+p_pgflibraryplothandlers.code.tex
+File: pgfplotsoldpgfsupp_pgflibraryplothandlers.code.tex 2009/02/13 v2.10 (rcs-
+revision 1.7)
+\pgf@plot@mark@count=\count157
+\pgfplotmarksize=\dimen192
+)
+(/usr/share/texmf/tex/generic/pgf/libraries/pgflibraryfpu.code.tex))
+(/usr/share/texmf-texlive/tex/generic/pgfplots/util/pgfplotsutil.code.tex
+(/usr/share/texmf-texlive/tex/generic/pgfplots/liststructure/pgfplotsliststruct
+ure.code.tex)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/liststructure/pgfplotsliststruct
+ureext.code.tex)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/liststructure/pgfplotsarray.code
+.tex
+\c@pgfplotsarray@tmp=\count158
+)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/numtable/pgfplotstable.code.tex
+\c@pgfplotstable@counta=\count159
+\pgfplotstable@outfile=\write5
+
+(/usr/share/texmf-texlive/tex/generic/pgfplots/numtable/pgfplotstable.coltype.c
+ode.tex)))
+(/usr/share/texmf-texlive/tex/generic/pgfplots/util/pgfplotscolormap.code.tex)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/pgfplots.stackedplots.code.tex)
+(/usr/share/texmf-texlive/tex/generic/pgfplots/pgfplotscoordprocessing.code.tex
+) (/usr/share/texmf-texlive/tex/generic/pgfplots/pgfplotsticks.code.tex)
+(/usr/share/texmf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecor
+ations.code.tex
+(/usr/share/texmf/tex/generic/pgf/modules/pgfmoduledecorations.code.tex
+\pgfdecoratedcompleteddistance=\dimen193
+\pgfdecoratedremainingdistance=\dimen194
+\pgfdecoratedinputsegmentcompleteddistance=\dimen195
+\pgfdecoratedinputsegmentremainingdistance=\dimen196
+\pgf@decorate@distancetomove=\dimen197
+\pgf@decorate@repeatstate=\count160
+\pgfdecorationsegmentamplitude=\dimen198
+\pgfdecorationsegmentlength=\dimen199
)
\tikz@lib@dec@box=\box50
)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\frontendlayer\tikz\libraries\tikz
-librarydecorations.pathmorphing.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\libraries\decorations\pgflibraryd
-ecorations.pathmorphing.code.tex"))
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\frontendlayer\tikz\libraries\tikz
-librarydecorations.pathreplacing.code.tex"
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\libraries\decorations\pgflibraryd
-ecorations.pathreplacing.code.tex"))
-\pgfplots@numplots=\count181
-\pgfplots@xmin@reg=\dimen208
-\pgfplots@xmax@reg=\dimen209
-\pgfplots@ymin@reg=\dimen210
-\pgfplots@ymax@reg=\dimen211
-\pgfplots@zmin@reg=\dimen212
-\pgfplots@zmax@reg=\dimen213
-)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\frontendlayer\tikz\libraries\tikz
-libraryplotmarks.code.tex"
+(/usr/share/texmf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecor
+ations.pathmorphing.code.tex
+(/usr/share/texmf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.p
+athmorphing.code.tex))
+(/usr/share/texmf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecor
+ations.pathreplacing.code.tex
+(/usr/share/texmf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.p
+athreplacing.code.tex))
+\pgfplots@numplots=\count161
+\pgfplots@xmin@reg=\dimen200
+\pgfplots@xmax@reg=\dimen201
+\pgfplots@ymin@reg=\dimen202
+\pgfplots@ymax@reg=\dimen203
+\pgfplots@zmin@reg=\dimen204
+\pgfplots@zmax@reg=\dimen205
+)
+(/usr/share/texmf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryplotm
+arks.code.tex
File: tikzlibraryplotmarks.code.tex 2008/01/09 v2.10 (rcs-revision 1.1)
-("C:\Program Files\MiKTeX 2.9\tex\generic\pgf\libraries\pgflibraryplotmarks.cod
-e.tex"
+(/usr/share/texmf/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex
File: pgflibraryplotmarks.code.tex 2010/10/15 v2.10 (rcs-revision 1.12)
-))) ("C:\Program Files\MiKTeX 2.9\tex\latex\ltxmisc\url.sty"
+)))
+(/usr/share/texmf-texlive/tex/latex/ltxmisc/url.sty
\Urlmuskip=\muskip11
Package: url 2006/04/12 ver 3.3 Verb mode for urls, etc.
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\booktabs\booktabs.sty"
+(/usr/share/texmf-texlive/tex/latex/booktabs/booktabs.sty
Package: booktabs 2005/04/14 v1.61803 publication quality tables
-\heavyrulewidth=\dimen214
-\lightrulewidth=\dimen215
-\cmidrulewidth=\dimen216
-\belowrulesep=\dimen217
-\belowbottomsep=\dimen218
-\aboverulesep=\dimen219
-\abovetopsep=\dimen220
-\cmidrulesep=\dimen221
-\cmidrulekern=\dimen222
-\defaultaddspace=\dimen223
-\@cmidla=\count182
-\@cmidlb=\count183
-\@aboverulesep=\dimen224
-\@belowrulesep=\dimen225
-\@thisruleclass=\count184
-\@lastruleclass=\count185
-\@thisrulewidth=\dimen226
-)
-("C:\Program Files\MiKTeX 2.9\tex\latex\subfigure\subfigure.sty"
-Package: subfigure 2002/07/30 v2.1.4 subfigure package
+\heavyrulewidth=\dimen206
+\lightrulewidth=\dimen207
+\cmidrulewidth=\dimen208
+\belowrulesep=\dimen209
+\belowbottomsep=\dimen210
+\aboverulesep=\dimen211
+\abovetopsep=\dimen212
+\cmidrulesep=\dimen213
+\cmidrulekern=\dimen214
+\defaultaddspace=\dimen215
+\@cmidla=\count162
+\@cmidlb=\count163
+\@aboverulesep=\dimen216
+\@belowrulesep=\dimen217
+\@thisruleclass=\count164
+\@lastruleclass=\count165
+\@thisrulewidth=\dimen218
+)
+(/usr/share/texmf-texlive/tex/latex/subfigure/subfigure.sty
+Package: subfigure 2002/03/15 v2.1.5 subfigure package
\subfigtopskip=\skip65
\subfigcapskip=\skip66
-\subfigcaptopadj=\dimen227
+\subfigcaptopadj=\dimen219
\subfigbottomskip=\skip67
-\subfigcapmargin=\dimen228
+\subfigcapmargin=\dimen220
\subfiglabelskip=\skip68
-\c@subfigure=\count186
-\c@lofdepth=\count187
-\c@subtable=\count188
-\c@lotdepth=\count189
+\c@subfigure=\count166
+\c@lofdepth=\count167
+\c@subtable=\count168
+\c@lotdepth=\count169
****************************************
* Local config file subfigure.cfg used *
****************************************
-("C:\Program Files\MiKTeX 2.9\tex\latex\subfigure\subfigure.cfg")
+(/usr/share/texmf-texlive/tex/latex/subfigure/subfigure.cfg)
\subfig@top=\skip69
\subfig@bottom=\skip70
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\koma-script\scrpage2.sty"
-Package: scrpage2 2010/04/22 v2.5 LaTeX2e KOMA-Script package
+(/usr/share/texmf-texlive/tex/latex/koma-script/scrpage2.sty
+Package: scrpage2 2008/12/08 v2.3 LaTeX2e KOMA-Script package
LaTeX Info: Redefining \pagemark on input line 176.
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\listings\lstlang1.sty"
+(/usr/share/texmf-texlive/tex/latex/listings/lstlang1.sty
File: lstlang1.sty 2004/09/05 1.3 listings language file
)
-\c@example=\count190
-\glo@main@file=\write5
+\c@example=\count170
+\glo@main@file=\write6
+\openout6 = `Master.glo'.
+
Package glossaries Info: Writing glossary file Master.glo on input line 93.
-\glo@acronym@file=\write6
+\glo@acronym@file=\write7
+\openout7 = `Master.acn'.
+
Package glossaries Info: Writing glossary file Master.acn on input line 93.
+ (./Glossary.tex)
+(./Master.aux)
+\openout1 = `Master.aux'.
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Glossary.tex)
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.aux)
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 110.
LaTeX Font Info: ... okay on input line 110.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 110.
@@ -1035,82 +937,116 @@ LaTeX Font Info: ... okay on input line 110.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 110.
LaTeX Font Info: ... okay on input line 110.
LaTeX Font Info: Try loading font information for T1+ptm on input line 110.
-
-("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\t1ptm.fd"
+ (/usr/share/texmf-texlive/tex/latex/psnfss/t1ptm.fd
File: t1ptm.fd 2001/06/04 font definitions for T1/ptm.
)
-("C:\Program Files\MiKTeX 2.9\tex\latex\unicode\ucsencs.def"
+Package scrbase Info: No captions found for `german'
+(scrbase) --> skipped on input line 110.
+Package scrbase Info: No captions found for `ngerman'
+(scrbase) --> skipped on input line 110.
+
+(/usr/share/texmf-texlive/tex/latex/ucs/ucsencs.def
File: ucsencs.def 2003/11/29 Fixes to fontencodings LGR, T3
)
-("C:\Program Files\MiKTeX 2.9\tex\context\base\supp-pdf.mkii"
+(/usr/share/texmf-texlive/tex/context/base/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
-\scratchcounter=\count191
-\scratchdimen=\dimen229
+\scratchcounter=\count171
+\scratchdimen=\dimen221
\scratchbox=\box51
-\nofMPsegments=\count192
-\nofMParguments=\count193
-\everyMPshowfont=\toks60
-\MPscratchCnt=\count194
-\MPscratchDim=\dimen230
-\MPnumerator=\count195
-\makeMPintoPDFobject=\count196
-\everyMPtoPDFconversion=\toks61
-)
-\c@lstlisting=\count197
-
-("C:\Program Files\MiKTeX 2.9\tex\latex\glossaries\dict\glossaries-dictionary-E
-nglish.dict"
+\nofMPsegments=\count172
+\nofMParguments=\count173
+\everyMPshowfont=\toks51
+\MPscratchCnt=\count174
+\MPscratchDim=\dimen222
+\MPnumerator=\count175
+\everyMPtoPDFconversion=\toks52
+)
+\c@lstlisting=\count176
+
+(/usr/share/texmf-texlive/tex/latex/glossaries/dict/glossaries-dictionary-Engli
+sh.dict
Dictionary: glossaries-dictionary, Language: English
-) ABD: EveryShipout initializing macros
-LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <10.95> not available
-(Font) Font shape `T1/ptm/b/n' tried instead on input line 120.
-
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\Abstract.tex) [1
-Non-PDF special ignored!
-Non-PDF special ignored!
-Non-PDF special ignored!
-Non-PDF special ignored!
+) ABD: EveryShipout initializing macros (./Titlepage.tex
+pdfTeX warning: pdflatex (file ../Images/unisiegel.pdf): PDF inclusion: found P
+DF version <1.5>, but at most version <1.4> allowed
+<../Images/unisiegel.pdf, id=4, 527.57097pt x 616.70403pt>
+File: ../Images/unisiegel.pdf Graphic file (type pdf)
-Non-PDF special ignored!
-Non-PDF special ignored!{C:/ProgramData/MiKTeX/2.9/pdftex/config/pdftex.map}]
-LaTeX Font Info: Try loading font information for U+msa on input line 130.
+<use ../Images/unisiegel.pdf>
+LaTeX Font Info: Font shape `T1/ptm/bx/sc' in size <20.74> not available
+(Font) Font shape `T1/ptm/b/sc' tried instead on input line 17.
+LaTeX Font Info: Try loading font information for U+msa on input line 26.
-("C:\Program Files\MiKTeX 2.9\tex\latex\amsfonts\umsa.fd"
+(/usr/share/texmf-texlive/tex/latex/amsfonts/umsa.fd
File: umsa.fd 2009/06/22 v3.00 AMS symbols A
)
-LaTeX Font Info: Try loading font information for U+msb on input line 130.
+LaTeX Font Info: Try loading font information for U+msb on input line 26.
-("C:\Program Files\MiKTeX 2.9\tex\latex\amsfonts\umsb.fd"
+(/usr/share/texmf-texlive/tex/latex/amsfonts/umsb.fd
File: umsb.fd 2009/06/22 v3.00 AMS symbols B
)
-LaTeX Font Info: Try loading font information for U+esvect on input line 130
-.
+LaTeX Font Info: Try loading font information for U+esvect on input line 26.
-("C:\Program Files\MiKTeX 2.9\tex\latex\esvect\uesvect.fd"
+
+(/usr/share/texmf-texlive/tex/latex/esvect/uesvect.fd
File: uesvect.fd
-) [2
+) [1
+Non-PDF special ignored!
+Non-PDF special ignored!
+Non-PDF special ignored!
+\openout3 = `Master.ist'.
-]
+{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map} <../Images/unisiegel.pdf>])
+LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <10.95> not available
+(Font) Font shape `T1/ptm/b/n' tried instead on input line 120.
+ (../Content/Abstract.tex) [2]
LaTeX Font Info: Try loading font information for T1+phv on input line 134.
-("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\t1phv.fd"
+(/usr/share/texmf-texlive/tex/latex/psnfss/t1phv.fd
File: t1phv.fd 2001/06/04 scalable font definitions for T1/phv.
)
LaTeX Font Info: Font shape `T1/phv/bx/n' in size <10.95> not available
(Font) Font shape `T1/phv/b/n' tried instead on input line 134.
LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <20.74> not available
(Font) Font shape `T1/ptm/b/n' tried instead on input line 134.
+ (./Master.toc
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 2.
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 4.
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 39.
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 52.
+ [1
+
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.toc [1
-])
-\tf@toc=\write7
-[2] (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\Motivation.tex
+]
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 57.
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 59.
+Class scrbook Info: You've told me to use the font selection of the element
+(scrbook) `sectioning' that is an alias of element `disposition'
+(scrbook) on input line 60.
+)
+\tf@toc=\write8
+\openout8 = `Master.toc'.
+
+
+[2] (../Content/Motivation.tex
Chapter 1.
Class scrbook Warning: \float@addtolists detected!
@@ -1121,7 +1057,7 @@ Class scrbook Warning: \float@addtolists detected!
LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <14.4> not available
(Font) Font shape `T1/ptm/b/n' tried instead on input line 8.
-) (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\GSM.tex [1
+) (../Content/GSM.tex [1
@@ -1134,7 +1070,7 @@ LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <14.4> not available
Chapter 2.
[3]
LaTeX Font Info: Try loading font information for OMS+ptm on input line 33.
- ("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\omsptm.fd"
+ (/usr/share/texmf-texlive/tex/latex/psnfss/omsptm.fd
File: omsptm.fd
)
LaTeX Font Info: Font shape `OMS/ptm/m/n' in size <10.95> not available
@@ -1142,166 +1078,105 @@ LaTeX Font Info: Font shape `OMS/ptm/m/n' in size <10.95> not available
[4]
LaTeX Font Info: Try loading font information for T1+pcr on input line 85.
-("C:\Program Files\MiKTeX 2.9\tex\latex\psnfss\t1pcr.fd"
+(/usr/share/texmf-texlive/tex/latex/psnfss/t1pcr.fd
File: t1pcr.fd 2001/06/04 font definitions for T1/pcr.
)
-<../Images/Architecture.png, id=39, 370.45602pt x 204.81319pt>
+<../Images/Architecture.png, id=42, 370.45602pt x 204.81319pt>
File: ../Images/Architecture.png Graphic file (type png)
-<use ../Images/Architecture.png>
-Package pdftex.def Info: ../Images/Architecture.png used on input line 95.
-(pdftex.def) Requested size: 370.45511pt x 204.81267pt.
- [5]
+<use ../Images/Architecture.png> [5]
LaTeX Font Info: Font shape `T1/ptm/bx/n' in size <12> not available
(Font) Font shape `T1/ptm/b/n' tried instead on input line 117.
- [6 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Architecture.png>]
-[7]
+ [6 <../Images/Architecture.png (PNG copy)>] [7]
Underfull \vbox (badness 2042) has occurred while \output is active []
[8]
-[9] [10] [11] <../Images/Authentication.png, id=63, 359.1819pt x 323.0469pt>
+[9] [10] [11] <../Images/Authentication.png, id=66, 359.1819pt x 323.0469pt>
File: ../Images/Authentication.png Graphic file (type png)
-<use ../Images/Authentication.png>
-Package pdftex.def Info: ../Images/Authentication.png used on input line 343.
-(pdftex.def) Requested size: 359.18102pt x 323.04611pt.
- [12] [13 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Authenticatio
-n.png>] [14]
-<../Images/Mapping.png, id=73, 337.28409pt x 115.19838pt>
+<use ../Images/Authentication.png> [12] [13 <../Images/Authentication.png (PNG
+copy)>] [14] <../Images/Mapping.png, id=76, 337.28409pt x 115.19838pt>
File: ../Images/Mapping.png Graphic file (type png)
-<use ../Images/Mapping.png>
-Package pdftex.def Info: ../Images/Mapping.png used on input line 420.
-(pdftex.def) Requested size: 337.28326pt x 115.19809pt.
- [15] [16 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Mapping.png>]
- [17]
-<../Images/Cells.png, id=84, 98.72083pt x 88.8921pt>
+<use ../Images/Mapping.png> [15] [16 <../Images/Mapping.png (PNG copy)>]
+[17] <../Images/Cells.png, id=87, 98.72083pt x 88.8921pt>
File: ../Images/Cells.png Graphic file (type png)
- <use ../Images/Cells.png>
-Package pdftex.def Info: ../Images/Cells.png used on input line 495.
-(pdftex.def) Requested size: 98.72057pt x 88.89188pt.
-
-<../Images/real_Cells.png, id=85, 743.02594pt x 496.10344pt>
-File: ../Images/real_Cells.png Graphic file (type png)
-<use ../Images/real_Cells.png>
-Package pdftex.def Info: ../Images/real_Cells.png used on input line 497.
-(pdftex.def) Requested size: 156.04005pt x 104.18478pt.
+<use ../Images/Cells.png>
+<../Images/real_Cells.PNG, id=88, 743.02594pt x 496.10344pt>
+File: ../Images/real_Cells.PNG Graphic file (type png)
-<../Images/standart_config.png, id=87, 199.4652pt x 133.26588pt>
-File: ../Images/standart_config.png Graphic file (type png)
+<use ../Images/real_Cells.PNG>
+<../Images/Standart_config.png, id=90, 199.4652pt x 133.26588pt>
+File: ../Images/Standart_config.png Graphic file (type png)
-<use ../Images/standart_config.png>
-Package pdftex.def Info: ../Images/standart_config.png used on input line 512.
-(pdftex.def) Requested size: 199.4647pt x 133.26553pt.
-
-<../Images/Umbrella.png, id=88, 209.3662pt x 181.46997pt>
+<use ../Images/Standart_config.png>
+<../Images/Umbrella.png, id=91, 209.3662pt x 181.46997pt>
File: ../Images/Umbrella.png Graphic file (type png)
<use ../Images/Umbrella.png>
-Package pdftex.def Info: ../Images/Umbrella.png used on input line 513.
-(pdftex.def) Requested size: 209.36568pt x 181.46951pt.
-
-<../Images/Sectorised.png, id=89, 147.64761pt x 147.64761pt>
+<../Images/Sectorised.png, id=92, 147.64761pt x 147.64761pt>
File: ../Images/Sectorised.png Graphic file (type png)
-<use ../Images/Sectorised.png>
-Package pdftex.def Info: ../Images/Sectorised.png used on input line 514.
-(pdftex.def) Requested size: 147.64725pt x 147.64725pt.
- [18 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Cells.png> <C:/Use
-rs/Tom/Desktop/imsi-catcher-detection/Tex/Images/real_Cells.png>] [19 <C:/Users
-/Tom/Desktop/imsi-catcher-detection/Tex/Images/standart_config.png> <C:/Users/T
-om/Desktop/imsi-catcher-detection/Tex/Images/Umbrella.png> <C:/Users/Tom/Deskto
-p/imsi-catcher-detection/Tex/Images/Sectorised.png>] [20] [21] <../Images/Ciphe
-r.png, id=105, 387.72855pt x 131.02551pt>
+<use ../Images/Sectorised.png> [18 <../Images/Cells.png (PNG copy)> <../Images/
+real_Cells.PNG>] [19 <../Images/Standart_config.png (PNG copy)> <../Images/Umbr
+ella.png (PNG copy)> <../Images/Sectorised.png (PNG copy)>] [20] [21]
+<../Images/Cipher.png, id=108, 387.72855pt x 131.02551pt>
File: ../Images/Cipher.png Graphic file (type png)
-<use ../Images/Cipher.png>
-Package pdftex.def Info: ../Images/Cipher.png used on input line 602.
-(pdftex.def) Requested size: 387.72758pt x 131.02518pt.
- [22 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Cipher.png>]
-<../Images/TDMAFDMA.png, id=110, 254.53494pt x 133.33815pt>
+<use ../Images/Cipher.png> [22 <../Images/Cipher.png (PNG copy)>]
+<../Images/TDMAFDMA.png, id=113, 254.53494pt x 133.33815pt>
File: ../Images/TDMAFDMA.png Graphic file (type png)
<use ../Images/TDMAFDMA.png>
-Package pdftex.def Info: ../Images/TDMAFDMA.png used on input line 643.
-(pdftex.def) Requested size: 254.5343pt x 133.33781pt.
-
Underfull \vbox (badness 10000) has occurred while \output is active []
- [23 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/TDMAFDMA.png>]
-<../Images/Frames.png, id=114, 367.42068pt x 252.29457pt>
+ [23 <../Images/TDMAFDMA.png (PNG copy)>]
+<../Images/Frames.png, id=117, 367.42068pt x 252.29457pt>
File: ../Images/Frames.png Graphic file (type png)
-<use ../Images/Frames.png>
-Package pdftex.def Info: ../Images/Frames.png used on input line 665.
-(pdftex.def) Requested size: 367.41977pt x 252.29395pt.
- [24] [25 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Frames.png>]
-<../Images/Bursts.png, id=121, 371.9737pt x 91.92744pt>
+<use ../Images/Frames.png> [24] [25 <../Images/Frames.png (PNG copy)>]
+<../Images/Bursts.png, id=124, 371.9737pt x 91.92744pt>
File: ../Images/Bursts.png Graphic file (type png)
-<use ../Images/Bursts.png>
-Package pdftex.def Info: ../Images/Bursts.png used on input line 690.
-(pdftex.def) Requested size: 371.97278pt x 91.9272pt.
- [26 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Bursts.png>]
-<../Images/Channels.png, id=125, 272.60245pt x 169.47314pt>
+<use ../Images/Bursts.png> [26 <../Images/Bursts.png (PNG copy)>]
+<../Images/Channels.png, id=128, 272.60245pt x 169.47314pt>
File: ../Images/Channels.png Graphic file (type png)
-<use ../Images/Channels.png>
-Package pdftex.def Info: ../Images/Channels.png used on input line 726.
-(pdftex.def) Requested size: 272.60178pt x 169.47273pt.
- [27 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/Channels.png>] [28
-]
-<../Images/channel_example.png, id=133, 926.71219pt x 1127.71312pt>
+<use ../Images/Channels.png> [27 <../Images/Channels.png (PNG copy)>] [28]
+<../Images/channel_example.png, id=136, 926.71219pt x 1127.71312pt>
File: ../Images/channel_example.png Graphic file (type png)
-<use ../Images/channel_example.png>
-Package pdftex.def Info: ../Images/channel_example.png used on input line 811.
-(pdftex.def) Requested size: 349.53978pt x 425.35205pt.
- [29] [30] [31 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/channel_
-example.png>]
-<../Images/imsi_catcher.jpg, id=144, 280.15778pt x 225.73222pt>
+<use ../Images/channel_example.png> [29] [30] [31 <../Images/channel_example.pn
+g>] <../Images/imsi_catcher.jpg, id=147, 280.15778pt x 225.73222pt>
File: ../Images/imsi_catcher.jpg Graphic file (type jpg)
<use ../Images/imsi_catcher.jpg>
-Package pdftex.def Info: ../Images/imsi_catcher.jpg used on input line 866.
-(pdftex.def) Requested size: 174.76988pt x 140.81706pt.
-
-<../Images/usrp.jpg, id=145, 1204.5pt x 844.65562pt>
+<../Images/usrp.jpg, id=148, 1204.5pt x 844.65562pt>
File: ../Images/usrp.jpg Graphic file (type jpg)
<use ../Images/usrp.jpg>
-Package pdftex.def Info: ../Images/usrp.jpg used on input line 866.
-(pdftex.def) Requested size: 174.76988pt x 122.5557pt.
-
Underfull \vbox (badness 10000) has occurred while \output is active []
[32]
-<../Images/catcher_attack.png, id=150, 321.52924pt x 277.08318pt>
+<../Images/catcher_attack.png, id=153, 321.52924pt x 277.08318pt>
File: ../Images/catcher_attack.png Graphic file (type png)
-<use ../Images/catcher_attack.png>
-Package pdftex.def Info: ../Images/catcher_attack.png used on input line 883.
-(pdftex.def) Requested size: 321.52844pt x 277.08249pt.
- [33 <C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/imsi_catcher.jpg>
-<C:/Users/Tom/Desktop/imsi-catcher-detection/Tex/Images/usrp.jpg>] [34 <C:/User
-s/Tom/Desktop/imsi-catcher-detection/Tex/Images/catcher_attack.png>] [35]
-("C:\Program Files\MiKTeX 2.9\tex\latex\unicode\data\uni-0.def"
+<use ../Images/catcher_attack.png> [33 <../Images/imsi_catcher.jpg> <../Images/
+usrp.jpg>] [34 <../Images/catcher_attack.png (PNG copy)>] [35]
+(/usr/share/texmf-texlive/tex/latex/ucs/data/uni-0.def
File: uni-0.def 2004/10/17 UCS: Unicode data U+0000..U+00FF
) [36])
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\Detection.tex [37]
-[38
+(../Content/Detection.tex [37] [38
]
Chapter 3.
-) (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\Evaluation.tex
-[39] [40
+) (../Content/Evaluation.tex [39] [40
]
Chapter 4.
-) (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\Conclusion.tex
-[41] [42
+) (../Content/Conclusion.tex [41] [42
]
@@ -1310,7 +1185,7 @@ Chapter 5.
-] (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.bbl
+] (./Master.bbl
Underfull \hbox (badness 2818) in paragraph at lines 17--21
[]\T1/ptm/m/n/10.95 Radio ac-cess net-work: Ra-dio trans-mis-sion and re-cep-ti
on. GSM 05.05,
@@ -1318,8 +1193,8 @@ on. GSM 05.05,
Underfull \hbox (badness 10000) in paragraph at lines 17--21
-$\T1/pcr/m/n/10.95 http : / / www . 3gpp . org / ftp / Specs / archive / 05 _ s
-eries / 05 .$
+\T1/pcr/m/n/10.95 http : / / www . 3gpp . org / ftp / Specs / archive / 05 _ se
+ries / 05 .
[]
@@ -1330,26 +1205,26 @@ O/IEC 7810:2003,
Underfull \hbox (badness 10000) in paragraph at lines 30--34
-$\T1/pcr/m/n/10.95 http : / / www . iso . org / iso / iso _ catalogue / catalog
-ue _ tc /$
+\T1/pcr/m/n/10.95 http : / / www . iso . org / iso / iso _ catalogue / catalogu
+e _ tc /
[]
Underfull \hbox (badness 10000) in paragraph at lines 36--40
-$\T1/pcr/m/n/10.95 3gpp . org / ftp / Specs / archive / 05 _ series / 05 . 02 /
- 0502-[]8b0 . zip$\T1/ptm/m/n/10.95 ,
+\T1/pcr/m/n/10.95 3gpp . org / ftp / Specs / archive / 05 _ series / 05 . 02 /
+0502-[]8b0 . zip$\T1/ptm/m/n/10.95 ,
[]
Underfull \hbox (badness 10000) in paragraph at lines 42--46
-$\T1/pcr/m/n/10.95 http : / / www . 3gpp . org / ftp / Specs / archive / 23 _ s
-eries / 23 . 078 /$
+\T1/pcr/m/n/10.95 http : / / www . 3gpp . org / ftp / Specs / archive / 23 _ se
+ries / 23 . 078 /
[]
Underfull \hbox (badness 10000) in paragraph at lines 48--52
-$\T1/pcr/m/n/10.95 org / ftp / Specs / archive / 23 _ series / 23 . 003 / 23003
--[]a30 . zip$\T1/ptm/m/n/10.95 ,
+\T1/pcr/m/n/10.95 org / ftp / Specs / archive / 23 _ series / 23 . 003 / 23003-
+[]a30 . zip$\T1/ptm/m/n/10.95 ,
[]
[1
@@ -1370,29 +1245,31 @@ Underfull \hbox (badness 10000) in paragraph at lines 121--126
Underfull \hbox (badness 10000) in paragraph at lines 121--126
\T1/ptm/m/n/10.95 bau. $\T1/pcr/m/n/10.95 http : / / www . heise . de / securi
-ty / meldung /$
+ty / meldung /
[]
Underfull \hbox (badness 10000) in paragraph at lines 121--126
-$\T1/pcr/m/n/10.95 IMSI-[]Catcher-[]fuer-[]1500-[]Euro-[]im-[]Eigenbau-[]104891
-9 . html$\T1/ptm/m/n/10.95 ,
+\T1/pcr/m/n/10.95 IMSI-[]Catcher-[]fuer-[]1500-[]Euro-[]im-[]Eigenbau-[]1048919
+ . html$\T1/ptm/m/n/10.95 ,
[]
-) [2] (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.lof)
-\tf@lof=\write8
+) [2] (./Master.lof)
+\tf@lof=\write9
+\openout9 = `Master.lof'.
-[3
+ [3
] [4
-] (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.lot)
-\tf@lot=\write9
+] (./Master.lot)
+\tf@lot=\write10
+\openout10 = `Master.lot'.
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Content\Appendix.tex)
-(C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.acr [5] [6
+ (../Content/Appendix.tex)
+(./Master.acr [5] [6
]
@@ -1408,31 +1285,30 @@ Underfull \hbox (badness 10000) in paragraph at lines 34--35
[7
-] [8]) [9] (C:\Users\Tom\Desktop\imsi-catcher-detection\Tex\Master\Master.aux)
-)
+] [8]) [9] (./Master.aux) )
Here is how much of TeX's memory you used:
- 29135 strings out of 494045
- 580489 string characters out of 3148393
- 815742 words of memory out of 3000000
- 31754 multiletter control sequences out of 15000+200000
- 52205 words of font info for 90 fonts, out of 3000000 for 9000
- 715 hyphenation exceptions out of 8191
- 74i,13n,83p,1323b,1590s stack positions out of 5000i,500n,10000p,200000b,50000s
-{C:/Program Files/MiKTeX 2.9/fonts/enc/dvips/fontname/8r.enc}<C:/Program Files
-/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmmi10.pfb><C:/Program Files/MiKTeX
-2.9/fonts/type1/public/amsfonts/cm/cmmi12.pfb><C:/Program Files/MiKTeX 2.9/font
-s/type1/public/amsfonts/cm/cmmi8.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/p
-ublic/amsfonts/cm/cmr10.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/ams
-fonts/cm/cmr8.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/c
-msy10.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmsy8.pfb
-><C:/Program Files/MiKTeX 2.9/fonts/type1/public/eurosym/feymr10.pfb><C:/Progra
-m Files/MiKTeX 2.9/fonts/type1/urw/courier/ucrr8a.pfb><C:/Program Files/MiKTeX
-2.9/fonts/type1/urw/times/utmb8a.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/u
-rw/times/utmr8a.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/urw/times/utmr8a.p
-fb><C:/Program Files/MiKTeX 2.9/fonts/type1/urw/times/utmri8a.pfb>
-Output written on Master.pdf (57 pages, 4253860 bytes).
+ 23891 strings out of 493848
+ 449217 string characters out of 1152824
+ 656934 words of memory out of 3000000
+ 26539 multiletter control sequences out of 15000+50000
+ 73495 words of font info for 100 fonts, out of 3000000 for 9000
+ 714 hyphenation exceptions out of 8191
+ 69i,13n,72p,1076b,1342s stack positions out of 5000i,500n,10000p,200000b,50000s
+{/usr/share/texmf-texlive/fonts/enc/dvips/base/8r.en
+c}</usr/share/texmf-texlive/fonts/type1/public/amsfonts/cm/cmmi10.pfb></usr/sha
+re/texmf-texlive/fonts/type1/public/amsfonts/cm/cmmi12.pfb></usr/share/texmf-te
+xlive/fonts/type1/public/amsfonts/cm/cmmi8.pfb></usr/share/texmf-texlive/fonts/
+type1/public/amsfonts/cm/cmr10.pfb></usr/share/texmf-texlive/fonts/type1/public
+/amsfonts/cm/cmr8.pfb></usr/share/texmf-texlive/fonts/type1/public/amsfonts/cm/
+cmsy10.pfb></usr/share/texmf-texlive/fonts/type1/public/amsfonts/cm/cmsy8.pfb><
+/usr/share/texmf-texlive/fonts/type1/public/eurosym/feymr10.pfb></usr/share/tex
+mf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share/texmf-texlive/fonts/t
+ype1/urw/times/utmb8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmr8
+a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/te
+xmf-texlive/fonts/type1/urw/times/utmri8a.pfb>
+Output written on Master.pdf (57 pages, 6427011 bytes).
PDF statistics:
- 262 PDF objects out of 1000 (max. 8388607)
+ 265 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
- 98 words of extra memory for PDF output out of 10000 (max. 10000000)
+ 103 words of extra memory for PDF output out of 10000 (max. 10000000)
diff --git a/Tex/Master/Master.pdf b/Tex/Master/Master.pdf
index 8430188..61d93fe 100644
--- a/Tex/Master/Master.pdf
+++ b/Tex/Master/Master.pdf
Binary files differ
diff --git a/Tex/Master/Master.synctex.gz b/Tex/Master/Master.synctex.gz
new file mode 100644
index 0000000..6ea7e59
--- /dev/null
+++ b/Tex/Master/Master.synctex.gz
Binary files differ
diff --git a/Tex/Master/Master.tex b/Tex/Master/Master.tex
index fb7525d..7355213 100644
--- a/Tex/Master/Master.tex
+++ b/Tex/Master/Master.tex
@@ -14,7 +14,7 @@
% Includes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%\usepackage{titlepage}
+\usepackage{titlepage}
\usepackage{eurosym}
%\usepackage{a4wide}
%\usepackage{caption}
@@ -109,7 +109,7 @@
\begin{document}
-%\input{Titlepage}
+\input{Titlepage}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Abstract %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/Tex/Master/Master.toc b/Tex/Master/Master.toc
index 062a494..6ef6921 100644
--- a/Tex/Master/Master.toc
+++ b/Tex/Master/Master.toc
@@ -32,8 +32,8 @@
\contentsline {section}{\numberline {2.4}IMSI-Catcher}{32}
\contentsline {subsection}{\numberline {2.4.1}Mode of Operation}{33}
\contentsline {subsubsection}{Attacks}{35}
-\contentsline {paragraph}{\gls {ms} is in normal cell selection mode:}{35}
-\contentsline {paragraph}{\gls {ms} is already connected to a network:}{35}
+\contentsline {paragraph}{MS is in normal cell selection mode:}{35}
+\contentsline {paragraph}{MS is already connected to a network:}{35}
\contentsline {subsubsection}{Risks and Irregularities}{36}
\contentsline {subsection}{\numberline {2.4.2}Law Situation in Germany}{36}
\contentsline {chapter}{\numberline {3}IMSI Catcher Detection}{39}
diff --git a/Tex/Master/titlepage.sty b/Tex/Master/titlepage.sty
new file mode 100644
index 0000000..4e81cc0
--- /dev/null
+++ b/Tex/Master/titlepage.sty
@@ -0,0 +1,402 @@
+%%
+%% This is file `titlepage.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% titlepage.dtx (with options: `package')
+%% Copyright (c) 2011 by Markus Kohm <komascript(at)gmx.info>
+%%
+%% This file was generated from file(s) of titlepage distribution.
+%% ----------------------------------------------------------------------
+%%
+%% This work may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, version 1.3c of the license.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status "maintained".
+%%
+%% The Current Maintainer and author of this work is Markus Kohm.
+%%
+%% This file may only be distributed together with the file
+%% `titlepage.dtx'. You may however distribute the file `titlepage.dtx'
+%% without this file.
+%%
+%% NOTE: THIS IS AN ALPHA-VERSION!
+\ProvidesPackage{titlepage%
+}[%
+ 2011/06/07 v0.2
+ KOMA presents the title page project
+]
+\RequirePackage{scrbase}[2011/06/07]
+\DefineFamily{title}
+\DefineFamilyMember{title}
+\newcommand*{\TitleOptions}{\FamilyOptions{title}}
+\newcommand*{\TitleOption}{\FamilyOption{title}}
+\newcounter{titlepage}\setcounter{titlepage}{\@ne}
+\DefineFamilyKey{title}{pagenumber}{\setcounter{titlepage}{#1}}
+\providecommand*{\titlepagestyle}{}
+\renewcommand*{\titlepagestyle}{empty}
+\DefineFamilyKey{title}{pagestyle}{\renewcommand*{\titlepagestyle}{#1}}
+\ifcsname @restonecolfalse\endcsname
+ \expandafter\@gobble
+\else
+ \expandafter\@firstofone
+\fi
+{\newif\if@restonecol}
+\scr@ifundefinedorrelax{titlepage}{\def\titlepage{}}{}
+\scr@ifundefinedorrelax{endtitlepage}{\def\endtitlepage{}}{}
+\providecommand*{\maketitle}[1][]{}
+\newcommand*{\tp@undefinedtitle}[1]{%
+ \PackageInfo{titlepage}{leaving not defined #1-title page empty}%
+}
+\newcommand*{\inittitle}{}
+\newcommand*{\makepretitle}{\tp@undefinedtitle{pre}}
+\newcommand*{\makepretitleback}{\tp@undefinedtitle{back of pre}}
+\newcommand*{\makemaintitle}{\tp@undefinedtitle{main}}
+\newcommand*{\makemaintitleback}{\tp@undefinedtitle{back of main}}
+\newcommand*{\makeposttitle}{\tp@undefinedtitle{post}}
+\newcommand*{\makeposttitleback}{\tp@undefinedtitle{back of post}}
+\newcommand*{\exittitle}{}
+\newcommand*{\inittitlestyle}{%
+ \renewenvironment{titlepage}[1][]{%
+ \TitleOptions{##1}%
+ \clearpage
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \else
+ \@restonecolfalse
+ \fi
+ \ifx\titlepagestyle\@empty\else\thispagestyle{\titlepagestyle}\fi
+ \ifodd\value{page}% aktuelle Seite ist ungerade
+ \ifodd\value{titlepage}%
+ \else
+ \null\newpage
+ \fi
+ \else
+ \ifodd\value{titlepage}%
+ \null\newpage % Leerseite
+ \fi
+ \fi
+ \setcounter{page}{\value{titlepage}}%
+ \ifx\titlepagestyle\@empty\else\thispagestyle{\titlepagestyle}\fi
+ }{%
+ \if@restonecol\twocolumn \else \newpage\fi
+ \stepcounter{titlepage}%
+ }%
+
+ \renewcommand*{\maketitle}[1][]{%
+ \begingroup
+ \TitleOptions{##1}%
+ \inittitle
+ \makepretitle\if@twoside\makepretitleback\fi
+ \makemaintitle\if@twoside\makemaintitleback\fi
+ \makeposttitle\if@twoside\makeposttitleback\fi
+ \exittitle
+ \endgroup
+ }%
+
+ \renewcommand*{\inittitle}{}%
+ \renewcommand*{\makepretitle}{\tp@undefinedtitle{pre}}%
+ \renewcommand*{\makepretitleback}{\tp@undefinedtitle{back of pre}}%
+ \renewcommand*{\makemaintitle}{\tp@undefinedtitle{main}}%
+ \renewcommand*{\makemaintitleback}{\tp@undefinedtitle{back of main}}%
+ \renewcommand*{\makeposttitle}{\tp@undefinedtitle{post}}%
+ \renewcommand*{\makeposttitleback}{\tp@undefinedtitle{back of post}}%
+ \renewcommand*{\exittitle}{}%
+}
+\inittitlestyle
+\newsavebox\titlebox
+\newenvironment{fullsizetitle}[1][]{%
+ \TitleOptions{#1}%
+ \begin{lrbox}{\titlebox}
+ \hsize\paperwidth
+ \scr@ifundefinedorrelax{ta@bcor}{%
+ \scr@ifundefinedorrelax{Gm@bindingoffset}{}{%
+ \advanve\hsize-\Gm@bindingoffset}%
+ }{%
+ \advance\hsize-\ta@bcor
+ \scr@ifundefinedorrelax{Gm@bindingoffset}{}{%
+ \ifdim \Gm@bindingoffset=\ta@bcor\else
+ \PackageWarning{titlepage}{ignorring geometry's binding
+ correction,\MessageBreak
+ using typearea's binding correction.\MessageBreak
+ If you're using geometry and typearea,\MessageBreak
+ you should set both options to same value,\MessageBreak
+ e.g. \string\KOMAoptions{BCOR=\ta@bcor}\MessageBreak
+ \space\space\space\space\space
+ \string\geometry{bindingoffset=\ta@bbcor}\MessageBreak
+ to make titlepage use this value%
+ }%
+ \fi
+ }%
+ }%
+ \vsize\paperheight
+ \linewidth\hsize
+ \columnwidth\hsize
+ \textwidth\hsize
+ \textheight\vsize
+ \noindent\minipage{\hsize}
+}{%
+ \endminipage
+ \end{lrbox}
+ \begin{titlepage}%
+ \vspace*{-1in}\vskip-\topmargin\vskip-\headheight\vskip-\headsep
+ \vskip-\topskip
+ \raggedright
+ \leavevmode
+ \hskip-1in
+ \ifodd\c@page
+ \hskip-\oddsidemargin
+ \scr@ifundefinedorrelax{ta@bcor}{%
+ \scr@ifundefinedorrelax{Gm@bindingoffset}{}{%
+ \hskip\Gm@bindingoffset}%
+ }{\hskip\ta@bcor}%
+ \else
+ \hskip-\evensidemargin
+ \fi
+ \vbox to\z@{\hsize\z@
+ \vskip-\baselineskip
+ \makebox[0pt][l]{\usebox\titlebox}%
+ \vss
+ }%
+ \end{titlepage}
+}
+\newcommand*{\tp@replacewarning}[2]{%
+ \PackageWarning{titlepage}{%
+ using `#2' instead of `#1',\MessageBreak
+ because `#1' not defined%
+ }%
+}
+\newcommand*{\tp@dokeys}{}
+\newcommand*{\DefineSimpleTitleKey}[2][.\@currname.\@currext]{%
+ \l@addto@macro\tp@dokeys{\do{#2}}%
+ \expandafter\newcommand\expandafter*\csname @#2\endcsname{}%
+ \expandafter\newcommand\expandafter*\csname #2\endcsname[1]{%
+ \expandafter\gdef\csname @#2\endcsname{##1}}%
+ \DefineFamilyKey[{#1}]{title}{#2}{\csname #2\endcsname{##1}}%
+}
+\newcommand*{\DefineReplaceTitleKey}[3][.\@currname.\@currext]{%
+ \DefineFamilyKey[{#1}]{title}{#2}{%
+ \tp@replacewarning{#2}{#3}%
+ \FamilyOptions{title}{#3=##1}%
+ }%
+}
+\providecommand*{\@titlehead}{}
+\providecommand{\titlehead}[1]{\gdef\@titlehead{#1}}
+\DefineFamilyKey{title}{titlehead}{\titlehead{#1}}
+\let\@title\relax\let\title\relax\DefineSimpleTitleKey{title}
+\let\@author\relax\let\author\relax\DefineSimpleTitleKey{author}
+\let\@date\relax\let\date\relax\DefineSimpleTitleKey{date}
+\DefineSimpleTitleKey{duration}
+\DefineSimpleTitleKey{course}
+\DefineSimpleTitleKey{company}
+\let\@subtitle\relax\let\subtitle\relax\DefineSimpleTitleKey{subtitle}
+\DefineSimpleTitleKey{university}
+\DefineSimpleTitleKey{faculty}
+\DefineSimpleTitleKey{chair}
+\DefineSimpleTitleKey{professor}
+\providecommand*{\@subject}{}
+\providecommand*{\subject}[1]{\gdef\@subject{#1}}
+\l@addto@macro\tp@dokeys{\do{subject}}%
+\DefineFamilyKey{title}{subject}{%
+ \ifstr{#1}{project}{\subject{\projectpapername}}{%
+ \ifstr{#1}{seminar}{\subject{\seminarpapername}}{%
+ \ifstr{#1}{studentreseach}{\subject{\studentreserachname}}{%
+ \ifstr{#1}{diploma}{\subject{\diplomathesisname}}{%
+ \ifstr{#1}{degree}{\subject{\degreethesisname}}{%
+ \ifstr{#1}{master}{\subject{\masterthesisname}}{%
+ \ifstr{#1}{bachelor}{\subject{\bachelorthesisname}}{%
+ \subject{#1}%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+ }%
+}
+\DefineReplaceTitleKey{student}{author}
+\DefineSimpleTitleKey{discipline}
+\DefineSimpleTitleKey{degree}
+\DefineSimpleTitleKey{matriculationnumber}
+\DefineSimpleTitleKey{advisor}
+\DefineSimpleTitleKey{referee}
+\DefineSimpleTitleKey{place}
+\DefineSimpleTitleKey{publisher}
+\renewcommand*{\@publisher}{\csname @publishers\endcsname}
+\DefineSimpleTitleKey{oralexaminationdate}
+\providecommand*{\@dedication}{}
+\providecommand{\dedication}[1]{\gdef\@dedication{#1}}
+\DefineFamilyKey{title}{dedication}{\dedication{#1}}
+\scr@ifundefinedorrelax{newkomafont}{
+ \newcommand*{\@titlepagefont}{}%
+}{%
+ \newkomafont{titlepage}{}%
+}
+\DefineFamilyKey{title}{titlepagefont}{%
+ \renewcommand*{\@titlepagefont}{#1}%
+}
+\providecommand*{\subject@font}{\bfseries}
+\DefineFamilyKey{title}{subjectfont}{%
+ \renewcommand*{\subject@font}{#1}%
+}
+\providecommand*{\titlefont}{\bfseries}
+\DefineFamilyKey{title}{titlefont}{%
+ \renewcommand*{\titlefont}{#1}%
+}
+\providecommand*{\@subtitlefont}{\bfseries}
+\DefineFamilyKey{title}{subtitlefont}{%
+ \renewcommand*{\@subtitlefont}{#1}%
+}
+\newcommand*{\TitlePageStyle}[2][]{%
+ \IfFileExists{title-#2.def}{%
+ \begingroup
+ \edef\@tempa{\endgroup
+ \noexpand\inittitlestyle
+ \noexpand\makeatletter
+ \noexpand\input{title-#2.def}%
+ \noexpand\catcode`\noexpand\@=\the\catcode`\@
+ }%
+ \@tempa
+ \TitleOptions{#1}%
+ }{%
+ \PackageError{titlepage}{No title definition for `#2' found}{%
+ You've tried to set title page style `#2', but no title page
+ style definition file\MessageBreak
+ `title-#2.def' may be found%
+ }%
+ }
+}
+\newcommand*{\NowButAfterBeginDocument}{%
+ \if@atdocument
+ \expandafter\@firstofone
+ \else
+ \expandafter\AtBeginDocument
+ \fi
+}
+\DeclareOption*{\expandafter\TitlePageStyle\expandafter{\CurrentOption}}
+\FamilyProcessOptions*\relax
+\providecommand*\projectpapername{Project Paper}
+\providecommand*\seminarpapername{Seminar Paper}
+\providecommand*\studentresearchname{Student Research Project}
+\providecommand*\diplomathesisname{Diploma Thesis}
+\providecommand*\degreethesisname{Degree Thesis}
+\providecommand*\masterthesisname{Master Thesis}
+\providecommand*\bachelorthesisname{Bachelor Thesis}
+\providecommand*{\presentedbyname}{presented by}
+\providecommand*{\advisorname}{Advisor}
+\providecommand*{\thename}{}
+\providecommand*{\ofthename}{of the}
+\providecommand*{\fromname}{from}
+\providecommand*{\fromplacename}{from}
+\providecommand*{\refereename}{Referee}
+\providecommand*{\oralexaminationdatename}{Date of Oral Examination}
+\providecommand*{\atthename}{at}
+\providecommand*{\durationname}{Processing Time}
+\providecommand*{\matriculationnumbername}{Matriculationnumber}
+\providecommand*{\coursename}{Course}
+\providecommand*{\companyname}{Training Company}
+\providecommand*{\examinationname}{Examination}
+\newcommand*{\ordinal}{\englishordinal}
+\AtBeginDocument{%
+ \providecaptionname{english}\projectpapername{Project Paper}%
+ \providecaptionname{english}\seminarpapername{Seminar Paper}%
+ \providecaptionname{english}\studentresearchname{Student Research Project}%
+ \providecaptionname{english}\diplomathesisname{Diploma Thesis}%
+ \providecaptionname{english}\degreethesisname{Degree Thesis}%
+ \providecaptionname{english}\masterthesisname{Master Thesis}%
+ \providecaptionname{english}\bachelorthesisname{Bachelor Thesis}%
+ \providecaptionname{english}{\ordinal}{\englishordinal}%
+ \providecaptionname{english}{\presentedbyname}{presented by}%
+ \providecaptionname{english}{\advisorname}{Advisor}%
+ \providecaptionname{english}{\thename}{}%
+ \providecaptionname{english}{\ofthename}{of the}%
+ \providecaptionname{english}{\fromname}{from}%
+ \providecaptionname{english}{\fromplacename}{from}%
+ \providecaptionname{english}{\refereename}{Referee}%
+ \providecaptionname{english}{\oralexaminationdatename}{Date of Oral
+ Examination}%
+ \providecaptionname{english}{\durationname}{Processing Time}%
+ \providecaptionname{english}{\matriculationnumbername}{Matriculationnumber}%
+ \providecaptionname{english}{\coursename}{Course}%
+ \providecaptionname{english}{\companyname}{Training Company}%
+ \providecaptionname{english}{\examinationname}{Examination}%
+ \providecaptionname{german}\projectpapername{Projektarbeit}%
+ \providecaptionname{german}\seminarpapername{Seminararbeit}%
+ \providecaptionname{german}\studentresearchname{Studienarbeit}%
+ \providecaptionname{german}\diplomathesisname{Diplomarbeit}%
+ \providecaptionname{german}\degreethesisname{Dissertation}%
+ \providecaptionname{german}\masterthesisname{Master-Arbeit}%
+ \providecaptionname{german}\bachelorthesisname{Bachelor-Arbeit}%
+ \providecaptionname{german}{\ordinal}{\germanordinal}%
+ \providecaptionname{german}{\presentedbyname}{eingereicht von}%
+ \providecaptionname{german}{\advisorname}{Betreuer}%
+ \providecaptionname{german}{\thename}{den}%
+ \providecaptionname{german}{\ofthename}{der}%
+ \providecaptionname{german}{\fromname}{von}%
+ \providecaptionname{german}{\fromplacename}{aus}%
+ \providecaptionname{german}{\refereename}{Gutachter}%
+ \providecaptionname{german}{\oralexaminationdatename}{Datum der m\"undlichen
+ Pr\"ufung}%
+ \providecaptionname{german}{\durationname}{Bearbeitungszeitraum}%
+ \providecaptionname{german}{\matriculationnumbername}{Matrikelnummer}%
+ \providecaptionname{german}{\coursename}{Kurs}%
+ \providecaptionname{german}{\companyname}{Ausbildungsfirma}%
+ \providecaptionname{german}{\examinationname}{Pr\"ufung}%
+ \providecaptionname{ngerman}\projectpapername{Projektarbeit}%
+ \providecaptionname{ngerman}\seminarpapername{Seminararbeit}%
+ \providecaptionname{ngerman}\studentresearchname{Studienarbeit}%
+ \providecaptionname{ngerman}\diplomathesisname{Diplomarbeit}%
+ \providecaptionname{ngerman}\degreethesisname{Dissertation}%
+ \providecaptionname{ngerman}\masterthesisname{Master-Arbeit}%
+ \providecaptionname{ngerman}\bachelorthesisname{Bachelor-Arbeit}%
+ \providecaptionname{ngerman}{\ordinal}{\germanordinal}%
+ \providecaptionname{ngerman}{\presentedbyname}{eingereicht von}%
+ \providecaptionname{ngerman}{\advisorname}{Betreuer}%
+ \providecaptionname{ngerman}{\thename}{den}%
+ \providecaptionname{ngerman}{\ofthename}{der}%
+ \providecaptionname{ngerman}{\fromname}{von}%
+ \providecaptionname{ngerman}{\fromplacename}{aus}%
+ \providecaptionname{ngerman}{\refereename}{Gutachter}%
+ \providecaptionname{ngerman}{\oralexaminationdatename}{Datum der m\"undlichen
+ Pr\"ufung}%
+ \providecaptionname{ngerman}{\durationname}{Bearbeitungszeitraum}%
+ \providecaptionname{ngerman}{\matriculationnumbername}{Matrikelnummer}%
+ \providecaptionname{ngerman}{\coursename}{Kurs}%
+ \providecaptionname{ngerman}{\companyname}{Ausbildungsfirma}%
+ \providecaptionname{ngerman}{\examinationname}{Pr\"ufung}%
+}
+\newcommand*{\englishordinal}[1]{%
+ \ifcsname engordnumber\endcsname
+ \engordnumber{#1}%
+ \else
+ \ifnum #1<\@ne
+ \PackageError{titlepage}{ordinal of `#1' not defined}{%
+ This package does only define english ordinals from 1}%
+ \else
+ \ifcase #1\or 1st\or 2nd\or 3rd\or 4th\or 5th\or 6th\or 7th\or 8th\or
+ 9th\or 10th\else
+ \PackageError{titlepage}{ordinal of `#1' not defined}{%
+ This package does only define english ordinals from 1 to
+ 10.\MessageBreak
+ You may load package `engord' to improve support of english
+ ordinals}%
+ \fi
+ \fi
+ \fi
+}
+\newcommand*{\germanordinal}[1]{%
+ \ifnum #1<\@ne
+ \PackageError{titlepage}{ordinal of `#1' not defined}{%
+ This package does only define german ordinals from 1}%
+ \else
+ #1.%
+ \fi
+}
+\endinput
+%%
+%% End of file `titlepage.sty'.