laforge-slides/2017/path_loss_link_budget-osmoc.../path_loss_link_budget.html

5040 lines
141 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Path Loss and Link Budget</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="copyright" content="Copyright &#169; 2017 by Harald Welte (License: CC-BY-SA)" />
<meta name="generator" content="AsciiDoc 8.6.9" />
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
/* Default font. */
body {
font-family: Georgia,serif;
}
/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
font-family: Arial,Helvetica,sans-serif;
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
h5 {
font-size: 1.0em;
}
div.sectionbody {
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
ul > li { color: #aaa; }
ul > li > * { color: black; }
.monospaced, code, pre {
font-family: "Courier New", Courier, monospace;
font-size: inherit;
color: navy;
padding: 0;
margin: 0;
}
pre {
white-space: pre-wrap;
}
#author {
color: #527bbd;
font-weight: bold;
font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}
#footer {
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
#footer-text {
float: left;
padding-bottom: 0.5em;
}
#footer-badges {
float: right;
padding-bottom: 0.5em;
}
#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.0em;
margin-bottom: 2.0em;
margin-right: 10%;
color: #606060;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid #dddddd;
border-left: 4px solid #f0f0f0;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid #dddddd;
border-left: 5px solid #f0f0f0;
background: #f8f8f8;
padding: 0.5em;
}
div.quoteblock, div.verseblock {
padding-left: 1.0em;
margin-left: 1.0em;
margin-right: 10%;
border-left: 5px solid #f0f0f0;
color: #888;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock > pre.content {
font-family: inherit;
font-size: inherit;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 3px solid #dddddd;
}
div.exampleblock > div.content {
border-left: 3px solid #dddddd;
padding-left: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
.footnote, .footnoteref {
font-size: 0.8em;
}
span.footnote, span.footnoteref {
vertical-align: super;
}
#footnotes {
margin: 20px 0 20px 0;
padding: 7px 0 0 0;
}
#footnotes div.footnote {
margin: 0 0 5px 0;
}
#footnotes hr {
border: none;
border-top: 1px solid silver;
height: 1px;
text-align: left;
margin-left: 0;
width: 20%;
min-width: 100px;
}
div.colist td {
padding-right: 0.5em;
padding-bottom: 0.3em;
vertical-align: top;
}
div.colist td img {
margin-top: 0.3em;
}
@media print {
#footer-badges { display: none; }
}
#toc {
margin-bottom: 2.5em;
}
#toctitle {
color: #527bbd;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }
span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }
span.big { font-size: 2em; }
span.small { font-size: 0.6em; }
span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }
div.unbreakable { page-break-inside: avoid; }
/*
* xhtml11 specific
*
* */
div.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead, p.table.header {
font-weight: bold;
color: #527bbd;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
/*
* html5 specific
*
* */
table.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
thead, p.tableblock.header {
font-weight: bold;
color: #527bbd;
}
p.tableblock {
margin-top: 0;
}
table.tableblock {
border-width: 3px;
border-spacing: 0px;
border-style: solid;
border-color: #527bbd;
border-collapse: collapse;
}
th.tableblock, td.tableblock {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #527bbd;
}
table.tableblock.frame-topbot {
border-left-style: hidden;
border-right-style: hidden;
}
table.tableblock.frame-sides {
border-top-style: hidden;
border-bottom-style: hidden;
}
table.tableblock.frame-none {
border-style: hidden;
}
th.tableblock.halign-left, td.tableblock.halign-left {
text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
text-align: right;
}
th.tableblock.valign-top, td.tableblock.valign-top {
vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
vertical-align: bottom;
}
/*
* manpage specific
*
* */
body.manpage h1 {
padding-top: 0.5em;
padding-bottom: 0.5em;
border-top: 2px solid silver;
border-bottom: 2px solid silver;
}
body.manpage h2 {
border-style: none;
}
body.manpage div.sectionbody {
margin-left: 3em;
}
@media print {
body.manpage div#toc { display: none; }
}
/* slidy.css
Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
W3C liability, trademark, document use and software licensing
rules apply, see:
http://www.w3.org/Consortium/Legal/copyright-documents
http://www.w3.org/Consortium/Legal/copyright-software
*/
/*
SJR: 2010-09-29: Modified for AsciiDoc slidy backend.
Mostly just commented out stuff that is handled by AsciiDoc's CSS files.
*/
body
{
margin: 0 0 0 0;
padding: 0 0 0 0;
width: 100%;
height: 100%;
color: black;
background-color: white;
/*
font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif;
*/
font-size: 14pt;
}
div.toolbar {
position: fixed; z-index: 200;
top: auto; bottom: 0; left: 0; right: 0;
height: 1.2em; text-align: right;
padding-left: 1em;
padding-right: 1em;
font-size: 60%;
color: red;
background-color: rgb(240,240,240);
border-top: solid 1px rgb(180,180,180);
}
div.toolbar span.copyright {
color: black;
margin-left: 0.5em;
}
div.initial_prompt {
position: absolute;
z-index: 1000;
bottom: 1.2em;
width: 90%;
background-color: rgb(200,200,200);
opacity: 0.35;
background-color: rgb(200,200,200, 0.35);
cursor: pointer;
}
div.initial_prompt p.help {
text-align: center;
}
div.initial_prompt p.close {
text-align: right;
font-style: italic;
}
div.slidy_toc {
position: absolute;
z-index: 300;
width: 60%;
max-width: 30em;
height: 30em;
overflow: auto;
top: auto;
right: auto;
left: 4em;
bottom: 4em;
padding: 1em;
background: rgb(240,240,240);
border-style: solid;
border-width: 2px;
font-size: 60%;
}
div.slidy_toc .toc_heading {
text-align: center;
width: 100%;
margin: 0;
margin-bottom: 1em;
border-bottom-style: solid;
border-bottom-color: rgb(180,180,180);
border-bottom-width: 1px;
}
div.slide {
z-index: 20;
margin: 0 0 0 0;
padding-top: 0;
padding-bottom: 0;
padding-left: 20px;
padding-right: 20px;
border-width: 0;
clear: both;
top: 0;
bottom: 0;
left: 0;
right: 0;
line-height: 120%;
background-color: transparent;
}
div.background {
display: none;
}
div.handout {
margin-left: 20px;
margin-right: 20px;
}
div.slide.titlepage {
text-align: center;
}
div.slide.titlepage.h1 {
padding-top: 10%;
}
div.slide h1 {
padding-left: 0;
padding-right: 20pt;
padding-top: 4pt;
padding-bottom: 4pt;
margin-top: 0;
margin-left: 0;
margin-right: 60pt;
margin-bottom: 0.5em;
display: block;
font-size: 160%;
line-height: 1.2em;
background: transparent;
}
div.toc {
position: absolute;
top: auto;
bottom: 4em;
left: 4em;
right: auto;
width: 60%;
max-width: 30em;
height: 30em;
border: solid thin black;
padding: 1em;
background: rgb(240,240,240);
color: black;
z-index: 300;
overflow: auto;
display: block;
visibility: visible;
}
div.toc-heading {
width: 100%;
border-bottom: solid 1px rgb(180,180,180);
margin-bottom: 1em;
text-align: center;
}
/*
pre {
font-size: 80%;
font-weight: bold;
line-height: 120%;
padding-top: 0.2em;
padding-bottom: 0.2em;
padding-left: 1em;
padding-right: 1em;
border-style: solid;
border-left-width: 1em;
border-top-width: thin;
border-right-width: thin;
border-bottom-width: thin;
border-color: #95ABD0;
color: #00428C;
background-color: #E4E5E7;
}
*/
/*
li pre { margin-left: 0; }
blockquote { font-style: italic }
img { background-color: transparent }
p.copyright { font-size: smaller }
*/
.center { text-align: center }
.footnote { font-size: smaller; margin-left: 2em; }
/*
a img { border-width: 0; border-style: none }
*/
a:visited { color: navy }
a:link { color: navy }
a:hover { color: red; text-decoration: underline }
a:active { color: red; text-decoration: underline }
a {text-decoration: none}
.navbar a:link {color: white}
.navbar a:visited {color: yellow}
.navbar a:active {color: red}
.navbar a:hover {color: red}
/*
ul { list-style-type: square; }
ul ul { list-style-type: disc; }
ul ul ul { list-style-type: circle; }
ul ul ul ul { list-style-type: disc; }
li { margin-left: 0.5em; margin-top: 0.5em; }
li li { font-size: 85%; font-style: italic }
li li li { font-size: 85%; font-style: normal }
*/
div dt
{
margin-left: 0;
margin-top: 1em;
margin-bottom: 0.5em;
font-weight: bold;
}
div dd
{
margin-left: 2em;
margin-bottom: 0.5em;
}
/*
p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table {
margin-left: 1em;
margin-right: 1em;
}
*/
p.subhead { font-weight: bold; margin-top: 2em; }
.smaller { font-size: smaller }
.bigger { font-size: 130% }
/*
td,th { padding: 0.2em }
*/
ul {
margin: 0.5em 1.5em 0.5em 1.5em;
padding: 0;
}
ol {
margin: 0.5em 1.5em 0.5em 1.5em;
padding: 0;
}
ul { list-style-type: square; }
ul ul { list-style-type: disc; }
ul ul ul { list-style-type: circle; }
ul ul ul ul { list-style-type: disc; }
/*
ul li {
list-style: square;
margin: 0.1em 0em 0.6em 0;
padding: 0 0 0 0;
line-height: 140%;
}
ol li {
margin: 0.1em 0em 0.6em 1.5em;
padding: 0 0 0 0px;
line-height: 140%;
list-style-type: decimal;
}
li ul li {
font-size: 85%;
font-style: italic;
list-style-type: disc;
background: transparent;
padding: 0 0 0 0;
}
li li ul li {
font-size: 85%;
font-style: normal;
list-style-type: circle;
background: transparent;
padding: 0 0 0 0;
}
li li li ul li {
list-style-type: disc;
background: transparent;
padding: 0 0 0 0;
}
li ol li {
list-style-type: decimal;
}
li li ol li {
list-style-type: decimal;
}
*/
/*
setting class="outline" on ol or ul makes it behave as an
ouline list where blocklevel content in li elements is
hidden by default and can be expanded or collapsed with
mouse click. Set class="expand" on li to override default
*/
ol.outline li:hover { cursor: pointer }
ol.outline li.nofold:hover { cursor: default }
ul.outline li:hover { cursor: pointer }
ul.outline li.nofold:hover { cursor: default }
ol.outline { list-style:decimal; }
ol.outline ol { list-style-type:lower-alpha }
ol.outline li.nofold {
padding: 0 0 0 20px;
background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
}
ol.outline li.unfolded {
padding: 0 0 0 20px;
background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
}
ol.outline li.folded {
padding: 0 0 0 20px;
background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
}
ol.outline li.unfolded:hover {
padding: 0 0 0 20px;
background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
}
ol.outline li.folded:hover {
padding: 0 0 0 20px;
background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
}
ul.outline li.nofold {
padding: 0 0 0 20px;
background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
}
ul.outline li.unfolded {
padding: 0 0 0 20px;
background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
}
ul.outline li.folded {
padding: 0 0 0 20px;
background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
}
ul.outline li.unfolded:hover {
padding: 0 0 0 20px;
background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
}
ul.outline li.folded:hover {
padding: 0 0 0 20px;
background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
}
/* for slides with class "title" in table of contents */
a.titleslide { font-weight: bold; font-style: italic }
/*
hide images for work around for save as bug
where browsers fail to save images used by CSS
*/
img.hidden { display: none; visibility: hidden }
div.initial_prompt { display: none; visibility: hidden }
div.slide {
visibility: visible;
position: inherit;
}
div.handout {
border-top-style: solid;
border-top-width: thin;
border-top-color: black;
}
@media screen {
.hidden { display: none; visibility: visible }
div.slide.hidden { display: block; visibility: visible }
div.handout.hidden { display: block; visibility: visible }
div.background { display: none; visibility: hidden }
body.single_slide div.initial_prompt { display: block; visibility: visible }
body.single_slide div.background { display: block; visibility: visible }
body.single_slide div.background.hidden { display: none; visibility: hidden }
body.single_slide .invisible { visibility: hidden }
body.single_slide .hidden { display: none; visibility: hidden }
body.single_slide div.slide { position: absolute }
body.single_slide div.handout { display: none; visibility: hidden }
}
@media print {
.hidden { display: block; visibility: visible }
/*
div.slide pre { font-size: 60%; padding-left: 0.5em; }
*/
div.toolbar { display: none; visibility: hidden; }
div.slidy_toc { display: none; visibility: hidden; }
div.background { display: none; visibility: hidden; }
div.slide { page-break-before: always }
/* :first-child isn't reliable for print media */
div.slide.first-slide { page-break-before: avoid }
}
/* SJR: AsciiDoc slidy backend tweaks */
ol, ul {
margin: 0.8em 1.5em 0.8em 1.8em;
}
li > ul, li > ol {
margin-top: 0.5em;
}
.outline > li.folded,
.outline > li.unfolded {
color: #527bbd;
}
ul > li{ color: #aaa; }
ul > li > *, ol > li > * { color: black; }
li {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
/* slidy.js
Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
W3C liability, trademark, document use and software licensing
rules apply, see:
http://www.w3.org/Consortium/Legal/copyright-documents
http://www.w3.org/Consortium/Legal/copyright-software
*/
// the slidy object implementation
var w3c_slidy = {
// classify which kind of browser we're running under
ns_pos: (typeof window.pageYOffset!='undefined'),
khtml: ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false),
opera: ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false),
ipad: ((navigator.userAgent).indexOf("iPad") >= 0 ? true : false),
iphone: ((navigator.userAgent).indexOf("iPhone") >= 0 ? true : false),
ie: (typeof document.all != "undefined" && !this.opera),
ie6: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 6") != -1),
ie7: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1),
ie8: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 8") != -1),
ie9: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 9") != -1),
keyboardless: (this.ipad || this.iphone),
// are we running as XHTML? (doesn't work on Opera)
is_xhtml: /xml/.test(document.contentType),
slide_number: 0, // integer slide count: 0, 1, 2, ...
slide_number_element: null, // element containing slide number
slides: [], // set to array of slide div's
notes: [], // set to array of handout div's
backgrounds: [], // set to array of background div's
toolbar: null, // element containing toolbar
title: null, // document title
last_shown: null, // last incrementally shown item
eos: null, // span element for end of slide indicator
toc: null, // table of contents
outline: null, // outline element with the focus
selected_text_len: 0, // length of drag selection on document
view_all: 0, // 1 to view all slides + handouts
want_toolbar: true, // user preference to show/hide toolbar
mouse_click_enabled: true, // enables left click for next slide
scroll_hack: 0, // IE work around for position: fixed
disable_slide_click: false, // used by clicked anchors
lang: "en", // updated to language specified by html file
help_anchor: null, // used for keyboard focus hack in showToolbar()
help_page: "http://www.w3.org/Talks/Tools/Slidy2/help/help.html",
help_text: "Navigate with mouse click, space bar, Cursor Left/Right, " +
"or Pg Up and Pg Dn. Use S and B to change font size.",
size_index: 0,
size_adjustment: 0,
sizes: new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt",
"22pt", "24pt", "26pt", "28pt", "30pt", "32pt"),
// needed for efficient resizing
last_width: 0,
last_height: 0,
// Needed for cross browser support for relative width/height on
// object elements. The work around is to save width/height attributes
// and then to recompute absolute width/height dimensions on resizing
objects: [],
// attach initialiation event handlers
set_up: function () {
var init = function() { w3c_slidy.init(); };
if (typeof window.addEventListener != "undefined")
window.addEventListener("load", init, false);
else
window.attachEvent("onload", init);
},
hide_slides: function () {
if (document.body && !w3c_slidy.initialized)
document.body.style.visibility = "hidden";
else
setTimeout(w3c_slidy.hide_slides, 50);
},
// hack to persuade IE to compute correct document height
// as needed for simulating fixed positioning of toolbar
ie_hack: function () {
window.resizeBy(0,-1);
window.resizeBy(0, 1);
},
init: function () {
//alert("slidy starting test 10");
document.body.style.visibility = "visible";
w3c_slidy_i18n.init();
this.add_toolbar();
this.wrap_implicit_slides();
this.collect_slides();
this.collect_notes();
this.collect_backgrounds();
this.objects = document.body.getElementsByTagName("object");
this.patch_anchors();
this.slide_number = this.find_slide_number(location.href);
window.offscreenbuffering = true;
this.size_adjustment = this.find_size_adjust();
this.time_left = this.find_duration();
this.hide_image_toolbar(); // suppress IE image toolbar popup
this.init_outliner(); // activate fold/unfold support
this.title = document.title;
// work around for opera bug
this.is_xhtml = (document.body.tagName == "BODY" ? false : true);
if (this.slides.length > 0)
{
var slide = this.slides[this.slide_number];
if (this.slide_number > 0)
{
this.set_visibility_all_incremental("visible");
this.last_shown = this.previous_incremental_item(null);
this.set_eos_status(true);
}
else
{
this.last_shown = null;
this.set_visibility_all_incremental("hidden");
this.set_eos_status(!this.next_incremental_item(this.last_shown));
}
this.set_location();
this.add_class(this.slides[0], "first-slide");
w3c_slidy.show_slide(slide);
}
this.toc = this.table_of_contents();
this.add_initial_prompt();
// bind event handlers without interfering with custom page scripts
// Tap events behave too weirdly to support clicks reliably on
// iPhone and iPad, so exclude these from click handler
if (!this.keyboardless)
this.add_listener(document.body, "click", this.mouse_button_click);
this.add_listener(document, "keydown", this.key_down);
this.add_listener(document, "keypress", this.key_press);
this.add_listener(window, "resize", this.resized);
this.add_listener(window, "scroll", this.scrolled);
this.add_listener(window, "unload", this.unloaded);
if (!document.body.onclick)
document.body.onclick = function () { };
this.single_slide_view();
//this.set_location();
this.resized();
if (this.ie7)
setTimeout(w3c_slidy.ie_hack, 100);
this.show_toolbar();
// for back button detection
setInterval(function () { w3c_slidy.check_location(); }, 200);
w3c_slidy.initialized = true;
},
// create div element with links to each slide
table_of_contents: function () {
var toc = this.create_element("div");
this.add_class(toc, "slidy_toc hidden");
//toc.setAttribute("tabindex", "0");
var heading = this.create_element("div");
this.add_class(heading, "toc-heading");
heading.innerHTML = "Table of Contents".localize();
toc.appendChild(heading);
var previous = null;
for (var i = 0; i < this.slides.length; ++i)
{
var title = this.has_class(this.slides[i], "title");
var num = document.createTextNode((i + 1) + ". ");
toc.appendChild(num);
var a = this.create_element("a");
a.setAttribute("href", "#(" + (i+1) + ")");
if (title)
this.add_class(a, "titleslide");
var name = document.createTextNode(this.slide_name(i));
a.appendChild(name);
a.onclick = w3c_slidy.toc_click;
a.onkeydown = w3c_slidy.toc_keydown;
a.previous = previous;
if (previous)
previous.next = a;
toc.appendChild(a);
if (i == 0)
toc.first = a;
if (i < this.slides.length - 1)
{
var br = this.create_element("br");
toc.appendChild(br);
}
previous = a;
}
toc.focus = function () {
if (this.first)
this.first.focus();
}
toc.onmouseup = w3c_slidy.mouse_button_up;
toc.onclick = function (e) {
e||(e=window.event);
if (w3c_slidy.selected_text_len <= 0)
w3c_slidy.hide_table_of_contents();
w3c_slidy.stop_propagation(e);
if (e.cancel != undefined)
e.cancel = true;
if (e.returnValue != undefined)
e.returnValue = false;
return false;
};
document.body.insertBefore(toc, document.body.firstChild);
return toc;
},
is_shown_toc: function () {
return !w3c_slidy.has_class(w3c_slidy.toc, "hidden");
},
show_table_of_contents: function () {
w3c_slidy.remove_class(w3c_slidy.toc, "hidden");
var toc = w3c_slidy.toc;
toc.focus();
if (w3c_slidy.ie7 && w3c_slidy.slide_number == 0)
setTimeout(w3c_slidy.ie_hack, 100);
},
hide_table_of_contents: function () {
w3c_slidy.add_class(w3c_slidy.toc, "hidden");
if (!w3c_slidy.opera)
w3c_slidy.help_anchor.focus();
},
toggle_table_of_contents: function () {
if (w3c_slidy.is_shown_toc())
w3c_slidy.hide_table_of_contents();
else
w3c_slidy.show_table_of_contents();
},
// called on clicking toc entry
toc_click: function (e) {
if (!e)
e = window.event;
var target = w3c_slidy.get_target(e);
if (target && target.nodeType == 1)
{
var uri = target.getAttribute("href");
if (uri)
{
//alert("going to " + uri);
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.last_shown = null;
w3c_slidy.set_location();
w3c_slidy.set_visibility_all_incremental("hidden");
w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
w3c_slidy.show_slide(slide);
//target.focus();
try
{
if (!w3c_slidy.opera)
w3c_slidy.help_anchor.focus();
}
catch (e)
{
}
}
}
w3c_slidy.hide_table_of_contents(e);
if (w3c_slidy.ie7) w3c_slidy.ie_hack();
w3c_slidy.stop_propagation(e);
return w3c_slidy.cancel(e);
},
// called onkeydown for toc entry
toc_keydown: function (event) {
var key;
if (!event)
var event = window.event;
// kludge around NS/IE differences
if (window.event)
key = window.event.keyCode;
else if (event.which)
key = event.which;
else
return true; // Yikes! unknown browser
// ignore event if key value is zero
// as for alt on Opera and Konqueror
if (!key)
return true;
// check for concurrent control/command/alt key
// but are these only present on mouse events?
if (event.ctrlKey || event.altKey)
return true;
if (key == 13)
{
var uri = this.getAttribute("href");
if (uri)
{
//alert("going to " + uri);
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.last_shown = null;
w3c_slidy.set_location();
w3c_slidy.set_visibility_all_incremental("hidden");
w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
w3c_slidy.show_slide(slide);
//target.focus();
try
{
if (!w3c_slidy.opera)
w3c_slidy.help_anchor.focus();
}
catch (e)
{
}
}
w3c_slidy.hide_table_of_contents();
if (self.ie7)
w3c_slidy.ie_hack();
return w3c_slidy.cancel(event);
}
if (key == 40 && this.next)
{
this.next.focus();
return w3c_slidy.cancel(event);
}
if (key == 38 && this.previous)
{
this.previous.focus();
return w3c_slidy.cancel(event);
}
return true;
},
// ### OBSOLETE ###
before_print: function () {
this.show_all_slides();
this.hide_toolbar();
alert("before print");
},
// ### OBSOLETE ###
after_print: function () {
if (!this.view_all)
{
this.single_slide_view();
this.show_toolbar();
}
alert("after print");
},
// ### OBSOLETE ###
print_slides: function () {
this.before_print();
window.print();
this.after_print();
},
// ### OBSOLETE ?? ###
toggle_view: function () {
if (this.view_all)
{
this.single_slide_view();
this.show_toolbar();
this.view_all = 0;
}
else
{
this.show_all_slides();
this.hide_toolbar();
this.view_all = 1;
}
},
// prepare for printing ### OBSOLETE ###
show_all_slides: function () {
this.remove_class(document.body, "single_slide");
this.set_visibility_all_incremental("visible");
},
// restore after printing ### OBSOLETE ###
single_slide_view: function () {
this.add_class(document.body, "single_slide");
this.set_visibility_all_incremental("visible");
this.last_shown = this.previous_incremental_item(null);
},
// suppress IE's image toolbar pop up
hide_image_toolbar: function () {
if (!this.ns_pos)
{
var images = document.getElementsByTagName("IMG");
for (var i = 0; i < images.length; ++i)
images[i].setAttribute("galleryimg", "no");
}
},
unloaded: function (e) {
//alert("unloaded");
},
// Safari and Konqueror don't yet support getComputedStyle()
// and they always reload page when location.href is updated
is_KHTML: function () {
var agent = navigator.userAgent;
return (agent.indexOf("KHTML") >= 0 ? true : false);
},
// find slide name from first h1 element
// default to document title + slide number
slide_name: function (index) {
var name = null;
var slide = this.slides[index];
var heading = this.find_heading(slide);
if (heading)
name = this.extract_text(heading);
if (!name)
name = this.title + "(" + (index + 1) + ")";
name.replace(/\&/g, "&amp;");
name.replace(/\</g, "&lt;");
name.replace(/\>/g, "&gt;");
return name;
},
// find first h1 element in DOM tree
find_heading: function (node) {
if (!node || node.nodeType != 1)
return null;
if (node.nodeName == "H1" || node.nodeName == "h1")
return node;
var child = node.firstChild;
while (child)
{
node = this.find_heading(child);
if (node)
return node;
child = child.nextSibling;
}
return null;
},
// recursively extract text from DOM tree
extract_text: function (node) {
if (!node)
return "";
// text nodes
if (node.nodeType == 3)
return node.nodeValue;
// elements
if (node.nodeType == 1)
{
node = node.firstChild;
var text = "";
while (node)
{
text = text + this.extract_text(node);
node = node.nextSibling;
}
return text;
}
return "";
},
// find copyright text from meta element
find_copyright: function () {
var name, content;
var meta = document.getElementsByTagName("meta");
for (var i = 0; i < meta.length; ++i)
{
name = meta[i].getAttribute("name");
content = meta[i].getAttribute("content");
if (name == "copyright")
return content;
}
return null;
},
find_size_adjust: function () {
var name, content, offset;
var meta = document.getElementsByTagName("meta");
for (var i = 0; i < meta.length; ++i)
{
name = meta[i].getAttribute("name");
content = meta[i].getAttribute("content");
if (name == "font-size-adjustment")
return 1 * content;
}
return 1;
},
// <meta name="duration" content="20" /> for 20 minutes
find_duration: function () {
var name, content, offset;
var meta = document.getElementsByTagName("meta");
for (var i = 0; i < meta.length; ++i)
{
name = meta[i].getAttribute("name");
content = meta[i].getAttribute("content");
if (name == "duration")
return 60000 * content;
}
return null;
},
replace_by_non_breaking_space: function (str) {
for (var i = 0; i < str.length; ++i)
str[i] = 160;
},
// ### CHECK ME ### is use of "li" okay for text/html?
// for XHTML do we also need to specify namespace?
init_outliner: function () {
var items = document.getElementsByTagName("li");
for (var i = 0; i < items.length; ++i)
{
var target = items[i];
if (!this.has_class(target.parentNode, "outline"))
continue;
target.onclick = this.outline_click;
/* ### more work needed for IE6
if (!this.ns_pos)
{
target.onmouseover = this.hover_outline;
target.onmouseout = this.unhover_outline;
}
*/
if (this.foldable(target))
{
target.foldable = true;
target.onfocus = function () {w3c_slidy.outline = this;};
target.onblur = function () {w3c_slidy.outline = null;};
if (!target.getAttribute("tabindex"))
target.setAttribute("tabindex", "0");
if (this.has_class(target, "expand"))
this.unfold(target);
else
this.fold(target);
}
else
{
this.add_class(target, "nofold");
target.visible = true;
target.foldable = false;
}
}
},
foldable: function (item) {
if (!item || item.nodeType != 1)
return false;
var node = item.firstChild;
while (node)
{
if (node.nodeType == 1 && this.is_block(node))
return true;
node = node.nextSibling;
}
return false;
},
// ### CHECK ME ### switch to add/remove "hidden" class
fold: function (item) {
if (item)
{
this.remove_class(item, "unfolded");
this.add_class(item, "folded");
}
var node = item ? item.firstChild : null;
while (node)
{
if (node.nodeType == 1 && this.is_block(node)) // element
{
w3c_slidy.add_class(node, "hidden");
}
node = node.nextSibling;
}
item.visible = false;
},
// ### CHECK ME ### switch to add/remove "hidden" class
unfold: function (item) {
if (item)
{
this.add_class(item, "unfolded");
this.remove_class(item, "folded");
}
var node = item ? item.firstChild : null;
while (node)
{
if (node.nodeType == 1 && this.is_block(node)) // element
{
w3c_slidy.remove_class(node, "hidden");
}
node = node.nextSibling;
}
item.visible = true;
},
outline_click: function (e) {
if (!e)
e = window.event;
var rightclick = false;
var target = w3c_slidy.get_target(e);
while (target && target.visible == undefined)
target = target.parentNode;
if (!target)
return true;
if (e.which)
rightclick = (e.which == 3);
else if (e.button)
rightclick = (e.button == 2);
if (!rightclick && target.visible != undefined)
{
if (target.foldable)
{
if (target.visible)
w3c_slidy.fold(target);
else
w3c_slidy.unfold(target);
}
w3c_slidy.stop_propagation(e);
e.cancel = true;
e.returnValue = false;
}
return false;
},
add_initial_prompt: function () {
var prompt = this.create_element("div");
prompt.setAttribute("class", "initial_prompt");
var p1 = this.create_element("p");
prompt.appendChild(p1);
p1.setAttribute("class", "help");
if (this.keyboardless)
p1.innerHTML = "Tap footer to move to next slide";
else
p1.innerHTML = "Space or Right Arrow to move to next " +
"slide, click help below for more details";
this.add_listener(prompt, "click", function (e) {
document.body.removeChild(prompt);
w3c_slidy.stop_propagation(e);
if (e.cancel != undefined)
e.cancel = true;
if (e.returnValue != undefined)
e.returnValue = false;
return false;
});
document.body.appendChild(prompt);
this.initial_prompt = prompt;
setTimeout(function() {document.body.removeChild(prompt);}, 5000);
},
add_toolbar: function () {
var counter, page;
this.toolbar = this.create_element("div");
this.toolbar.setAttribute("class", "toolbar");
// a reasonably behaved browser
if (this.ns_pos || !this.ie6)
{
var right = this.create_element("div");
right.setAttribute("style", "float: right; text-align: right");
counter = this.create_element("span")
counter.innerHTML = "slide".localize() + " n/m";
right.appendChild(counter);
this.toolbar.appendChild(right);
var left = this.create_element("div");
left.setAttribute("style", "text-align: left");
// global end of slide indicator
this.eos = this.create_element("span");
this.eos.innerHTML = "* ";
left.appendChild(this.eos);
var help = this.create_element("a");
help.setAttribute("href", this.help_page);
help.setAttribute("title", this.help_text.localize());
help.innerHTML = "help?".localize();
left.appendChild(help);
this.help_anchor = help; // save for focus hack
var gap1 = document.createTextNode(" ");
left.appendChild(gap1);
var contents = this.create_element("a");
contents.setAttribute("href", "javascript:w3c_slidy.toggle_table_of_contents()");
contents.setAttribute("title", "table of contents".localize());
contents.innerHTML = "contents?".localize();
left.appendChild(contents);
var gap2 = document.createTextNode(" ");
left.appendChild(gap2);
var copyright = this.find_copyright();
if (copyright)
{
var span = this.create_element("span");
span.className = "copyright";
span.innerHTML = copyright;
left.appendChild(span);
}
this.toolbar.setAttribute("tabindex", "0");
this.toolbar.appendChild(left);
}
else // IE6 so need to work around its poor CSS support
{
this.toolbar.style.position = (this.ie7 ? "fixed" : "absolute");
this.toolbar.style.zIndex = "200";
this.toolbar.style.width = "99.9%";
this.toolbar.style.height = "1.2em";
this.toolbar.style.top = "auto";
this.toolbar.style.bottom = "0";
this.toolbar.style.left = "0";
this.toolbar.style.right = "0";
this.toolbar.style.textAlign = "left";
this.toolbar.style.fontSize = "60%";
this.toolbar.style.color = "red";
this.toolbar.borderWidth = 0;
this.toolbar.className = "toolbar";
this.toolbar.style.background = "rgb(240,240,240)";
// would like to have help text left aligned
// and page counter right aligned, floating
// div's don't work, so instead use nested
// absolutely positioned div's.
var sp = this.create_element("span");
sp.innerHTML = "&nbsp;&nbsp;*&nbsp;";
this.toolbar.appendChild(sp);
this.eos = sp; // end of slide indicator
var help = this.create_element("a");
help.setAttribute("href", this.help_page);
help.setAttribute("title", this.help_text.localize());
help.innerHTML = "help?".localize();
this.toolbar.appendChild(help);
this.help_anchor = help; // save for focus hack
var gap1 = document.createTextNode(" ");
this.toolbar.appendChild(gap1);
var contents = this.create_element("a");
contents.setAttribute("href", "javascript:toggleTableOfContents()");
contents.setAttribute("title", "table of contents".localize());
contents.innerHTML = "contents?".localize();
this.toolbar.appendChild(contents);
var gap2 = document.createTextNode(" ");
this.toolbar.appendChild(gap2);
var copyright = this.find_copyright();
if (copyright)
{
var span = this.create_element("span");
span.innerHTML = copyright;
span.style.color = "black";
span.style.marginLeft = "0.5em";
this.toolbar.appendChild(span);
}
counter = this.create_element("div")
counter.style.position = "absolute";
counter.style.width = "auto"; //"20%";
counter.style.height = "1.2em";
counter.style.top = "auto";
counter.style.bottom = 0;
counter.style.right = "0";
counter.style.textAlign = "right";
counter.style.color = "red";
counter.style.background = "rgb(240,240,240)";
counter.innerHTML = "slide".localize() + " n/m";
this.toolbar.appendChild(counter);
}
// ensure that click isn't passed through to the page
this.toolbar.onclick =
function (e) {
if (!e)
e = window.event;
var target = e.target;
if (!target && e.srcElement)
target = e.srcElement;
// work around Safari bug
if (target && target.nodeType == 3)
target = target.parentNode;
w3c_slidy.stop_propagation(e);
if (target && target.nodeName.toLowerCase() != "a")
w3c_slidy.mouse_button_click(e);
};
this.slide_number_element = counter;
this.set_eos_status(false);
document.body.appendChild(this.toolbar);
},
// wysiwyg editors make it hard to use div elements
// e.g. amaya loses the div when you copy and paste
// this function wraps div elements around implicit
// slides which start with an h1 element and continue
// up to the next heading or div element
wrap_implicit_slides: function () {
var i, heading, node, next, div;
var headings = document.getElementsByTagName("h1");
if (!headings)
return;
for (i = 0; i < headings.length; ++i)
{
heading = headings[i];
if (heading.parentNode != document.body)
continue;
node = heading.nextSibling;
div = document.createElement("div");
this.add_class(div, "slide");
document.body.replaceChild(div, heading);
div.appendChild(heading);
while (node)
{
if (node.nodeType == 1 && // an element
(node.nodeName == "H1" ||
node.nodeName == "h1" ||
node.nodeName == "DIV" ||
node.nodeName == "div"))
break;
next = node.nextSibling;
node = document.body.removeChild(node);
div.appendChild(node);
node = next;
}
}
},
// return new array of all slides
collect_slides: function () {
var slides = new Array();
var divs = document.body.getElementsByTagName("div");
for (var i = 0; i < divs.length; ++i)
{
div = divs.item(i);
if (this.has_class(div, "slide"))
{
// add slide to collection
slides[slides.length] = div;
// hide each slide as it is found
this.add_class(div, "hidden");
// add dummy <br/> at end for scrolling hack
var node1 = document.createElement("br");
div.appendChild(node1);
var node2 = document.createElement("br");
div.appendChild(node2);
}
else if (this.has_class(div, "background"))
{ // work around for Firefox SVG reload bug
// which otherwise replaces 1st SVG graphic with 2nd
div.style.display = "block";
}
}
this.slides = slides;
},
// return new array of all <div class="handout">
collect_notes: function () {
var notes = new Array();
var divs = document.body.getElementsByTagName("div");
for (var i = 0; i < divs.length; ++i)
{
div = divs.item(i);
if (this.has_class(div, "handout"))
{
// add note to collection
notes[notes.length] = div;
// and hide it
this.add_class(div, "hidden");
}
}
this.notes = notes;
},
// return new array of all <div class="background">
// including named backgrounds e.g. class="background titlepage"
collect_backgrounds: function () {
var backgrounds = new Array();
var divs = document.body.getElementsByTagName("div");
for (var i = 0; i < divs.length; ++i)
{
div = divs.item(i);
if (this.has_class(div, "background"))
{
// add background to collection
backgrounds[backgrounds.length] = div;
// and hide it
this.add_class(div, "hidden");
}
}
this.backgrounds = backgrounds;
},
// set click handlers on all anchors
patch_anchors: function () {
var self = w3c_slidy;
var handler = function (event) {
// compare this.href with location.href
// for link to another slide in this doc
if (self.page_address(this.href) == self.page_address(location.href))
{
// yes, so find new slide number
var newslidenum = self.find_slide_number(this.href);
if (newslidenum != self.slide_number)
{
var slide = self.slides[self.slide_number];
self.hide_slide(slide);
self.slide_number = newslidenum;
slide = self.slides[self.slide_number];
self.show_slide(slide);
self.set_location();
}
}
else if (this.target == null)
location.href = this.href;
this.blur();
self.disable_slide_click = true;
};
var anchors = document.body.getElementsByTagName("a");
for (var i = 0; i < anchors.length; ++i)
{
if (window.addEventListener)
anchors[i].addEventListener("click", handler, false);
else
anchors[i].attachEvent("onclick", handler);
}
},
// ### CHECK ME ### see which functions are invoked via setTimeout
// either directly or indirectly for use of w3c_slidy vs this
show_slide_number: function () {
var timer = w3c_slidy.get_timer();
w3c_slidy.slide_number_element.innerHTML = timer + "slide".localize() + " " +
(w3c_slidy.slide_number + 1) + "/" + w3c_slidy.slides.length;
},
// every 200mS check if the location has been changed as a
// result of the user activating the Back button/menu item
// doesn't work for Opera < 9.5
check_location: function () {
var hash = location.hash;
if (w3c_slidy.slide_number > 0 && (hash == "" || hash == "#"))
w3c_slidy.goto_slide(0);
else if (hash.length > 2 && hash != "#("+(w3c_slidy.slide_number+1)+")")
{
var num = parseInt(location.hash.substr(2));
if (!isNaN(num))
w3c_slidy.goto_slide(num-1);
}
if (w3c_slidy.time_left && w3c_slidy.slide_number > 0)
{
w3c_slidy.show_slide_number();
if (w3c_slidy.time_left > 0)
w3c_slidy.time_left -= 200;
}
},
get_timer: function () {
var timer = "";
if (w3c_slidy.time_left)
{
var mins, secs;
secs = Math.floor(w3c_slidy.time_left/1000);
mins = Math.floor(secs / 60);
secs = secs % 60;
timer = (mins ? mins+"m" : "") + secs + "s ";
}
return timer;
},
// this doesn't push location onto history stack for IE
// for which a hidden iframe hack is needed: load page into
// the iframe with script that set's parent's location.hash
// but that won't work for standalone use unless we can
// create the page dynamically via a javascript: URL
set_location: function () {
var uri = w3c_slidy.page_address(location.href);
var hash = "#(" + (w3c_slidy.slide_number+1) + ")";
if (w3c_slidy.slide_number >= 0)
uri = uri + hash;
if (w3c_slidy.ie && !w3c_slidy.ie8)
w3c_slidy.push_hash(hash);
if (uri != location.href) // && !khtml
location.href = uri;
if (this.khtml)
hash = "(" + (w3c_slidy.slide_number+1) + ")";
if (!this.ie && location.hash != hash && location.hash != "")
location.hash = hash;
document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
w3c_slidy.show_slide_number();
},
page_address: function (uri) {
var i = uri.indexOf("#");
if (i < 0)
i = uri.indexOf("%23");
// check if anchor is entire page
if (i < 0)
return uri; // yes
return uri.substr(0, i);
},
// only used for IE6 and IE7
on_frame_loaded: function (hash) {
location.hash = hash;
var uri = w3c_slidy.page_address(location.href);
location.href = uri + hash;
},
// history hack with thanks to Bertrand Le Roy
push_hash: function (hash) {
if (hash == "") hash = "#(1)";
window.location.hash = hash;
var doc = document.getElementById("historyFrame").contentWindow.document;
doc.open("javascript:'<html></html>'");
// PWL modified this string literal to break the close script tag
// which otherwise gets parsed when incorporated
doc.write("<html><head><script type=\"text/javascript\">window.parent.w3c_slidy.on_frame_loaded('"+
(hash) + "');</" + "script></head><body>hello mum</body></html>");
doc.close();
},
// find current slide based upon location
// first find target anchor and then look
// for associated div element enclosing it
// finally map that to slide number
find_slide_number: function (uri) {
// first get anchor from page location
var i = uri.indexOf("#");
// check if anchor is entire page
if (i < 0)
return 0; // yes
var anchor = unescape(uri.substr(i+1));
// now use anchor as XML ID to find target
var target = document.getElementById(anchor);
if (!target)
{
// does anchor look like "(2)" for slide 2 ??
// where first slide is (1)
var re = /\((\d)+\)/;
if (anchor.match(re))
{
var num = parseInt(anchor.substring(1, anchor.length-1));
if (num > this.slides.length)
num = 1;
if (--num < 0)
num = 0;
return num;
}
// accept [2] for backwards compatibility
re = /\[(\d)+\]/;
if (anchor.match(re))
{
var num = parseInt(anchor.substring(1, anchor.length-1));
if (num > this.slides.length)
num = 1;
if (--num < 0)
num = 0;
return num;
}
// oh dear unknown anchor
return 0;
}
// search for enclosing slide
while (true)
{
// browser coerces html elements to uppercase!
if (target.nodeName.toLowerCase() == "div" &&
this.has_class(target, "slide"))
{
// found the slide element
break;
}
// otherwise try parent element if any
target = target.parentNode;
if (!target)
{
return 0; // no luck!
}
};
for (i = 0; i < slides.length; ++i)
{
if (slides[i] == target)
return i; // success
}
// oh dear still no luck
return 0;
},
previous_slide: function (incremental) {
if (!w3c_slidy.view_all)
{
var slide;
if ((incremental || w3c_slidy.slide_number == 0) && w3c_slidy.last_shown != null)
{
w3c_slidy.last_shown = w3c_slidy.hide_previous_item(w3c_slidy.last_shown);
w3c_slidy.set_eos_status(false);
}
else if (w3c_slidy.slide_number > 0)
{
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = w3c_slidy.slide_number - 1;
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.set_visibility_all_incremental("visible");
w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
w3c_slidy.set_eos_status(true);
w3c_slidy.show_slide(slide);
}
w3c_slidy.set_location();
if (!w3c_slidy.ns_pos)
w3c_slidy.refresh_toolbar(200);
}
},
next_slide: function (incremental) {
if (!w3c_slidy.view_all)
{
var slide, last = w3c_slidy.last_shown;
if (incremental || w3c_slidy.slide_number == w3c_slidy.slides.length - 1)
w3c_slidy.last_shown = w3c_slidy.reveal_next_item(w3c_slidy.last_shown);
if ((!incremental || w3c_slidy.last_shown == null) &&
w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
{
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = w3c_slidy.slide_number + 1;
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.last_shown = null;
w3c_slidy.set_visibility_all_incremental("hidden");
w3c_slidy.show_slide(slide);
}
else if (!w3c_slidy.last_shown)
{
if (last && incremental)
w3c_slidy.last_shown = last;
}
w3c_slidy.set_location();
w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
if (!w3c_slidy.ns_pos)
w3c_slidy.refresh_toolbar(200);
}
},
// to first slide with nothing revealed
// i.e. state at start of presentation
first_slide: function () {
if (!w3c_slidy.view_all)
{
var slide;
if (w3c_slidy.slide_number != 0)
{
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = 0;
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.last_shown = null;
w3c_slidy.set_visibility_all_incremental("hidden");
w3c_slidy.show_slide(slide);
}
w3c_slidy.set_eos_status(
!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
w3c_slidy.set_location();
}
},
// goto last slide with everything revealed
// i.e. state at end of presentation
last_slide: function () {
if (!w3c_slidy.view_all)
{
var slide;
w3c_slidy.last_shown = null; //revealNextItem(lastShown);
if (w3c_slidy.last_shown == null &&
w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
{
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = w3c_slidy.slides.length - 1;
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.set_visibility_all_incremental("visible");
w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
w3c_slidy.show_slide(slide);
}
else
{
w3c_slidy.set_visibility_all_incremental("visible");
w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
}
w3c_slidy.set_eos_status(true);
w3c_slidy.set_location();
}
},
// ### check this and consider add/remove class
set_eos_status: function (state) {
if (this.eos)
this.eos.style.color = (state ? "rgb(240,240,240)" : "red");
},
// first slide is 0
goto_slide: function (num) {
//alert("going to slide " + (num+1));
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.slide_number = num;
slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.last_shown = null;
w3c_slidy.set_visibility_all_incremental("hidden");
w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
w3c_slidy.show_slide(slide);
w3c_slidy.show_slide_number();
},
show_slide: function (slide) {
this.sync_background(slide);
window.scrollTo(0,0);
this.remove_class(slide, "hidden");
},
hide_slide: function (slide) {
this.add_class(slide, "hidden");
},
// show just the backgrounds pertinent to this slide
// when slide background-color is transparent
// this should now work with rgba color values
sync_background: function (slide) {
var background;
var bgColor;
if (slide.currentStyle)
bgColor = slide.currentStyle["backgroundColor"];
else if (document.defaultView)
{
var styles = document.defaultView.getComputedStyle(slide,null);
if (styles)
bgColor = styles.getPropertyValue("background-color");
else // broken implementation probably due Safari or Konqueror
{
//alert("defective implementation of getComputedStyle()");
bgColor = "transparent";
}
}
else
bgColor == "transparent";
if (bgColor == "transparent" ||
bgColor.indexOf("rgba") >= 0 ||
bgColor.indexOf("opacity") >= 0)
{
var slideClass = this.get_class_list(slide);
for (var i = 0; i < this.backgrounds.length; i++)
{
background = this.backgrounds[i];
var bgClass = this.get_class_list(background);
if (this.matching_background(slideClass, bgClass))
this.remove_class(background, "hidden");
else
this.add_class(background, "hidden");
}
}
else // forcibly hide all backgrounds
this.hide_backgrounds();
},
hide_backgrounds: function () {
for (var i = 0; i < this.backgrounds.length; i++)
{
background = this.backgrounds[i];
this.add_class(background, "hidden");
}
},
// compare classes for slide and background
matching_background: function (slideClass, bgClass) {
var i, count, pattern, result;
// define pattern as regular expression
pattern = /\w+/g;
// check background class names
result = bgClass.match(pattern);
for (i = count = 0; i < result.length; i++)
{
if (result[i] == "hidden")
continue;
if (result[i] == "background")
continue;
++count;
}
if (count == 0) // default match
return true;
// check for matches and place result in array
result = slideClass.match(pattern);
// now check if desired name is present for background
for (i = count = 0; i < result.length; i++)
{
if (result[i] == "hidden")
continue;
if (this.has_token(bgClass, result[i]))
return true;
}
return false;
},
resized: function () {
var width = 0;
if ( typeof( window.innerWidth ) == 'number' )
width = window.innerWidth; // Non IE browser
else if (document.documentElement && document.documentElement.clientWidth)
width = document.documentElement.clientWidth; // IE6
else if (document.body && document.body.clientWidth)
width = document.body.clientWidth; // IE4
var height = 0;
if ( typeof( window.innerHeight ) == 'number' )
height = window.innerHeight; // Non IE browser
else if (document.documentElement && document.documentElement.clientHeight)
height = document.documentElement.clientHeight; // IE6
else if (document.body && document.body.clientHeight)
height = document.body.clientHeight; // IE4
if (height && (width/height > 1.05*1024/768))
{
width = height * 1024.0/768;
}
// IE fires onresize even when only font size is changed!
// so we do a check to avoid blocking < and > actions
if (width != w3c_slidy.last_width || height != w3c_slidy.last_height)
{
if (width >= 1100)
w3c_slidy.size_index = 5; // 4
else if (width >= 1000)
w3c_slidy.size_index = 4; // 3
else if (width >= 800)
w3c_slidy.size_index = 3; // 2
else if (width >= 600)
w3c_slidy.size_index = 2; // 1
else if (width)
w3c_slidy.size_index = 0;
// add in font size adjustment from meta element e.g.
// <meta name="font-size-adjustment" content="-2" />
// useful when slides have too much content ;-)
if (0 <= w3c_slidy.size_index + w3c_slidy.size_adjustment &&
w3c_slidy.size_index + w3c_slidy.size_adjustment < w3c_slidy.sizes.length)
w3c_slidy.size_index = w3c_slidy.size_index + w3c_slidy.size_adjustment;
// enables cross browser use of relative width/height
// on object elements for use with SVG and Flash media
w3c_slidy.adjust_object_dimensions(width, height);
if (document.body.style.fontSize != w3c_slidy.sizes[w3c_slidy.size_index])
{
document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
}
w3c_slidy.last_width = width;
w3c_slidy.last_height = height;
// force reflow to work around Mozilla bug
if (w3c_slidy.ns_pos)
{
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.show_slide(slide);
}
// force correct positioning of toolbar
w3c_slidy.refresh_toolbar(200);
}
},
scrolled: function () {
if (w3c_slidy.toolbar && !w3c_slidy.ns_pos && !w3c_slidy.ie7)
{
w3c_slidy.hack_offset = w3c_slidy.scroll_x_offset();
// hide toolbar
w3c_slidy.toolbar.style.display = "none";
// make it reappear later
if (w3c_slidy.scrollhack == 0 && !w3c_slidy.view_all)
{
setTimeout(function () {w3c_slidy.show_toolbar(); }, 1000);
w3c_slidy.scrollhack = 1;
}
}
},
hide_toolbar: function () {
w3c_slidy.add_class(w3c_slidy.toolbar, "hidden");
window.focus();
},
// used to ensure IE refreshes toolbar in correct position
refresh_toolbar: function (interval) {
if (!w3c_slidy.ns_pos && !w3c_slidy.ie7)
{
w3c_slidy.hide_toolbar();
setTimeout(function () {w3c_slidy.show_toolbar(); }, interval);
}
},
// restores toolbar after short delay
show_toolbar: function () {
if (w3c_slidy.want_toolbar)
{
w3c_slidy.toolbar.style.display = "block";
if (!w3c_slidy.ns_pos)
{
// adjust position to allow for scrolling
var xoffset = w3c_slidy.scroll_x_offset();
w3c_slidy.toolbar.style.left = xoffset;
w3c_slidy.toolbar.style.right = xoffset;
// determine vertical scroll offset
//var yoffset = scrollYOffset();
// bottom is doc height - window height - scroll offset
//var bottom = documentHeight() - lastHeight - yoffset
//if (yoffset > 0 || documentHeight() > lastHeight)
// bottom += 16; // allow for height of scrollbar
w3c_slidy.toolbar.style.bottom = 0; //bottom;
}
w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden");
}
w3c_slidy.scrollhack = 0;
// set the keyboard focus to the help link on the
// toolbar to ensure that document has the focus
// IE doesn't always work with window.focus()
// and this hack has benefit of Enter for help
try
{
if (!w3c_slidy.opera)
w3c_slidy.help_anchor.focus();
}
catch (e)
{
}
},
// invoked via F key
toggle_toolbar: function () {
if (!w3c_slidy.view_all)
{
if (w3c_slidy.has_class(w3c_slidy.toolbar, "hidden"))
{
w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden")
w3c_slidy.want_toolbar = 1;
}
else
{
w3c_slidy.add_class(w3c_slidy.toolbar, "hidden")
w3c_slidy.want_toolbar = 0;
}
}
},
scroll_x_offset: function () {
if (window.pageXOffset)
return self.pageXOffset;
if (document.documentElement &&
document.documentElement.scrollLeft)
return document.documentElement.scrollLeft;
if (document.body)
return document.body.scrollLeft;
return 0;
},
scroll_y_offset: function () {
if (window.pageYOffset)
return self.pageYOffset;
if (document.documentElement &&
document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (document.body)
return document.body.scrollTop;
return 0;
},
// looking for a way to determine height of slide content
// the slide itself is set to the height of the window
optimize_font_size: function () {
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
//var dh = documentHeight(); //getDocHeight(document);
var dh = slide.scrollHeight;
var wh = getWindowHeight();
var u = 100 * dh / wh;
alert("window utilization = " + u + "% (doc "
+ dh + " win " + wh + ")");
},
// from document object
get_doc_height: function (doc) {
if (!doc)
doc = document;
if (doc && doc.body && doc.body.offsetHeight)
return doc.body.offsetHeight; // ns/gecko syntax
if (doc && doc.body && doc.body.scrollHeight)
return doc.body.scrollHeight;
alert("couldn't determine document height");
},
get_window_height: function () {
if ( typeof( window.innerHeight ) == 'number' )
return window.innerHeight; // Non IE browser
if (document.documentElement && document.documentElement.clientHeight)
return document.documentElement.clientHeight; // IE6
if (document.body && document.body.clientHeight)
return document.body.clientHeight; // IE4
},
document_height: function () {
var sh, oh;
sh = document.body.scrollHeight;
oh = document.body.offsetHeight;
if (sh && oh)
{
return (sh > oh ? sh : oh);
}
// no idea!
return 0;
},
smaller: function () {
if (w3c_slidy.size_index > 0)
{
--w3c_slidy.size_index;
}
w3c_slidy.toolbar.style.display = "none";
document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.show_slide(slide);
setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
},
bigger: function () {
if (w3c_slidy.size_index < w3c_slidy.sizes.length - 1)
{
++w3c_slidy.size_index;
}
w3c_slidy.toolbar.style.display = "none";
document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
w3c_slidy.hide_slide(slide);
w3c_slidy.show_slide(slide);
setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
},
// enables cross browser use of relative width/height
// on object elements for use with SVG and Flash media
// with thanks to Ivan Herman for the suggestion
adjust_object_dimensions: function (width, height) {
for( var i = 0; i < w3c_slidy.objects.length; i++ )
{
var obj = this.objects[i];
var mimeType = obj.getAttribute("type");
if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash")
{
if ( !obj.initialWidth )
obj.initialWidth = obj.getAttribute("width");
if ( !obj.initialHeight )
obj.initialHeight = obj.getAttribute("height");
if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" )
{
var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1));
var newW = width * (w/100.0);
obj.setAttribute("width",newW);
}
if ( obj.initialHeight &&
obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" )
{
var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1));
var newH = height * (h/100.0);
obj.setAttribute("height", newH);
}
}
}
},
// needed for Opera to inhibit default behavior
// since Opera delivers keyPress even if keyDown
// was cancelled
key_press: function (event) {
if (!event)
event = window.event;
if (!w3c_slidy.key_wanted)
return w3c_slidy.cancel(event);
return true;
},
// See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes
key_down: function (event) {
var key;
w3c_slidy.key_wanted = true;
if (!event)
event = window.event;
// kludge around NS/IE differences
if (window.event)
key = window.event.keyCode;
else if (event.which)
key = event.which;
else
return true; // Yikes! unknown browser
// ignore event if key value is zero
// as for alt on Opera and Konqueror
if (!key)
return true;
// check for concurrent control/command/alt key
// but are these only present on mouse events?
if (event.ctrlKey || event.altKey || event.metaKey)
return true;
// dismiss table of contents if visible
if (w3c_slidy.is_shown_toc() && key != 9 && key != 16 && key != 38 && key != 40)
{
w3c_slidy.hide_table_of_contents();
if (key == 27 || key == 84 || key == 67)
return w3c_slidy.cancel(event);
}
if (key == 34) // Page Down
{
if (w3c_slidy.view_all)
return true;
w3c_slidy.next_slide(false);
return w3c_slidy.cancel(event);
}
else if (key == 33) // Page Up
{
if (w3c_slidy.view_all)
return true;
w3c_slidy.previous_slide(false);
return w3c_slidy.cancel(event);
}
else if (key == 32) // space bar
{
w3c_slidy.next_slide(true);
return w3c_slidy.cancel(event);
}
else if (key == 37) // Left arrow
{
w3c_slidy.previous_slide(!event.shiftKey);
return w3c_slidy.cancel(event);
}
else if (key == 36) // Home
{
w3c_slidy.first_slide();
return w3c_slidy.cancel(event);
}
else if (key == 35) // End
{
w3c_slidy.last_slide();
return w3c_slidy.cancel(event);
}
else if (key == 39) // Right arrow
{
w3c_slidy.next_slide(!event.shiftKey);
return w3c_slidy.cancel(event);
}
else if (key == 13) // Enter
{
if (w3c_slidy.outline)
{
if (w3c_slidy.outline.visible)
w3c_slidy.fold(w3c_slidy.outline);
else
w3c_slidy.unfold(w3c_slidy.outline);
return w3c_slidy.cancel(event);
}
}
else if (key == 188) // < for smaller fonts
{
w3c_slidy.smaller();
return w3c_slidy.cancel(event);
}
else if (key == 190) // > for larger fonts
{
w3c_slidy.bigger();
return w3c_slidy.cancel(event);
}
else if (key == 189 || key == 109) // - for smaller fonts
{
w3c_slidy.smaller();
return w3c_slidy.cancel(event);
}
else if (key == 187 || key == 191 || key == 107) // = + for larger fonts
{
w3c_slidy.bigger();
return w3c_slidy.cancel(event);
}
else if (key == 83) // S for smaller fonts
{
w3c_slidy.smaller();
return w3c_slidy.cancel(event);
}
else if (key == 66) // B for larger fonts
{
w3c_slidy.bigger();
return w3c_slidy.cancel(event);
}
else if (key == 90) // Z for last slide
{
w3c_slidy.last_slide();
return w3c_slidy.cancel(event);
}
else if (key == 70) // F for toggle toolbar
{
w3c_slidy.toggle_toolbar();
return w3c_slidy.cancel(event);
}
else if (key == 65) // A for toggle view single/all slides
{
w3c_slidy.toggle_view();
return w3c_slidy.cancel(event);
}
else if (key == 75) // toggle action of left click for next page
{
w3c_slidy.mouse_click_enabled = !w3c_slidy.mouse_click_enabled;
var alert_msg = (w3c_slidy.mouse_click_enabled ?
"enabled" : "disabled") + " mouse click advance";
alert(alert_msg.localize());
return w3c_slidy.cancel(event);
}
else if (key == 84 || key == 67) // T or C for table of contents
{
if (w3c_slidy.toc)
w3c_slidy.toggle_table_of_contents();
return w3c_slidy.cancel(event);
}
else if (key == 72) // H for help
{
window.location = w3c_slidy.help_page;
return w3c_slidy.cancel(event);
}
//else alert("key code is "+ key);
return true;
},
// safe for both text/html and application/xhtml+xml
create_element: function (name) {
if (this.xhtml && (typeof document.createElementNS != 'undefined'))
return document.createElementNS("http://www.w3.org/1999/xhtml", name)
return document.createElement(name);
},
get_element_style: function (elem, IEStyleProp, CSSStyleProp) {
if (elem.currentStyle)
{
return elem.currentStyle[IEStyleProp];
}
else if (window.getComputedStyle)
{
var compStyle = window.getComputedStyle(elem, "");
return compStyle.getPropertyValue(CSSStyleProp);
}
return "";
},
// the string str is a whitespace separated list of tokens
// test if str contains a particular token, e.g. "slide"
has_token: function (str, token) {
if (str)
{
// define pattern as regular expression
var pattern = /\w+/g;
// check for matches
// place result in array
var result = str.match(pattern);
// now check if desired token is present
for (var i = 0; i < result.length; i++)
{
if (result[i] == token)
return true;
}
}
return false;
},
get_class_list: function (element) {
if (typeof element.className != 'undefined')
return element.className;
return element.getAttribute("class");
},
has_class: function (element, name) {
if (element.nodeType != 1)
return false;
var regexp = new RegExp("(^| )" + name + "\W*");
if (typeof element.className != 'undefined')
return regexp.test(element.className);
return regexp.test(element.getAttribute("class"));
},
remove_class: function (element, name) {
var regexp = new RegExp("(^| )" + name + "\W*");
var clsval = "";
if (typeof element.className != 'undefined')
{
clsval = element.className;
if (clsval)
{
clsval = clsval.replace(regexp, "");
element.className = clsval;
}
}
else
{
clsval = element.getAttribute("class");
if (clsval)
{
clsval = clsval.replace(regexp, "");
element.setAttribute("class", clsval);
}
}
},
add_class: function (element, name) {
if (!this.has_class(element, name))
{
if (typeof element.className != 'undefined')
element.className += " " + name;
else
{
var clsval = element.getAttribute("class");
clsval = clsval ? clsval + " " + name : name;
element.setAttribute("class", clsval);
}
}
},
// HTML elements that can be used with class="incremental"
// note that you can also put the class on containers like
// up, ol, dl, and div to make their contents appear
// incrementally. Upper case is used since this is what
// browsers report for HTML node names (text/html).
incremental_elements: null,
okay_for_incremental: function (name) {
if (!this.incremental_elements)
{
var inclist = new Array();
inclist["p"] = true;
inclist["pre"] = true;
inclist["li"] = true;
inclist["blockquote"] = true;
inclist["dt"] = true;
inclist["dd"] = true;
inclist["h2"] = true;
inclist["h3"] = true;
inclist["h4"] = true;
inclist["h5"] = true;
inclist["h6"] = true;
inclist["span"] = true;
inclist["address"] = true;
inclist["table"] = true;
inclist["tr"] = true;
inclist["th"] = true;
inclist["td"] = true;
inclist["img"] = true;
inclist["object"] = true;
this.incremental_elements = inclist;
}
return this.incremental_elements[name.toLowerCase()];
},
next_incremental_item: function (node) {
var br = this.is_xhtml ? "br" : "BR";
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
for (;;)
{
node = w3c_slidy.next_node(slide, node);
if (node == null || node.parentNode == null)
break;
if (node.nodeType == 1) // ELEMENT
{
if (node.nodeName == br)
continue;
if (w3c_slidy.has_class(node, "incremental")
&& w3c_slidy.okay_for_incremental(node.nodeName))
return node;
if (w3c_slidy.has_class(node.parentNode, "incremental")
&& !w3c_slidy.has_class(node, "non-incremental"))
return node;
}
}
return node;
},
previous_incremental_item: function (node) {
var br = this.is_xhtml ? "br" : "BR";
var slide = w3c_slidy.slides[w3c_slidy.slide_number];
for (;;)
{
node = w3c_slidy.previous_node(slide, node);
if (node == null || node.parentNode == null)
break;
if (node.nodeType == 1)
{
if (node.nodeName == br)
continue;
if (w3c_slidy.has_class(node, "incremental")
&& w3c_slidy.okay_for_incremental(node.nodeName))
return node;
if (w3c_slidy.has_class(node.parentNode, "incremental")
&& !w3c_slidy.has_class(node, "non-incremental"))
return node;
}
}
return node;
},
// set visibility for all elements on current slide with
// a parent element with attribute class="incremental"
set_visibility_all_incremental: function (value) {
var node = this.next_incremental_item(null);
if (value == "hidden")
{
while (node)
{
w3c_slidy.add_class(node, "invisible");
node = w3c_slidy.next_incremental_item(node);
}
}
else // value == "visible"
{
while (node)
{
w3c_slidy.remove_class(node, "invisible");
node = w3c_slidy.next_incremental_item(node);
}
}
},
// reveal the next hidden item on the slide
// node is null or the node that was last revealed
reveal_next_item: function (node) {
node = w3c_slidy.next_incremental_item(node);
if (node && node.nodeType == 1) // an element
w3c_slidy.remove_class(node, "invisible");
return node;
},
// exact inverse of revealNextItem(node)
hide_previous_item: function (node) {
if (node && node.nodeType == 1) // an element
w3c_slidy.add_class(node, "invisible");
return this.previous_incremental_item(node);
},
// left to right traversal of root's content
next_node: function (root, node) {
if (node == null)
return root.firstChild;
if (node.firstChild)
return node.firstChild;
if (node.nextSibling)
return node.nextSibling;
for (;;)
{
node = node.parentNode;
if (!node || node == root)
break;
if (node && node.nextSibling)
return node.nextSibling;
}
return null;
},
// right to left traversal of root's content
previous_node: function (root, node) {
if (node == null)
{
node = root.lastChild;
if (node)
{
while (node.lastChild)
node = node.lastChild;
}
return node;
}
if (node.previousSibling)
{
node = node.previousSibling;
while (node.lastChild)
node = node.lastChild;
return node;
}
if (node.parentNode != root)
return node.parentNode;
return null;
},
previous_sibling_element: function (el) {
el = el.previousSibling;
while (el && el.nodeType != 1)
el = el.previousSibling;
return el;
},
next_sibling_element: function (el) {
el = el.nextSibling;
while (el && el.nodeType != 1)
el = el.nextSibling;
return el;
},
first_child_element: function (el) {
var node;
for (node = el.firstChild; node; node = node.nextSibling)
{
if (node.nodeType == 1)
break;
}
return node;
},
first_tag: function (element, tag) {
var node;
if (!this.is_xhtml)
tag = tag.toUpperCase();
for (node = element.firstChild; node; node = node.nextSibling)
{
if (node.nodeType == 1 && node.nodeName == tag)
break;
}
return node;
},
hide_selection: function () {
if (window.getSelection) // Firefox, Chromium, Safari, Opera
{
var selection = window.getSelection();
if (selection.rangeCount > 0)
{
var range = selection.getRangeAt(0);
range.collapse (false);
}
}
else // Internet Explorer
{
var textRange = document.selection.createRange ();
textRange.collapse (false);
}
},
get_selected_text: function () {
try
{
if (window.getSelection)
return window.getSelection().toString();
if (document.getSelection)
return document.getSelection().toString();
if (document.selection)
return document.selection.createRange().text;
}
catch (e)
{
}
return "";
},
// make note of length of selected text
// as this evaluates to zero in click event
mouse_button_up: function (e) {
w3c_slidy.selected_text_len = w3c_slidy.get_selected_text().length;
},
// right mouse button click is reserved for context menus
// it is more reliable to detect rightclick than leftclick
mouse_button_click: function (e) {
var rightclick = false;
var leftclick = false;
var middleclick = false;
var target;
if (!e)
var e = window.event;
if (e.target)
target = e.target;
else if (e.srcElement)
target = e.srcElement;
// work around Safari bug
if (target.nodeType == 3)
target = target.parentNode;
if (e.which) // all browsers except IE
{
leftclick = (e.which == 1);
middleclick = (e.which == 2);
rightclick = (e.which == 3);
}
else if (e.button)
{
// Konqueror gives 1 for left, 4 for middle
// IE6 gives 0 for left and not 1 as I expected
if (e.button == 4)
middleclick = true;
// all browsers agree on 2 for right button
rightclick = (e.button == 2);
}
else leftclick = true;
/*
alert("you clicked over a " + target.nodeName + " element\n" +
"w3c_slidy.mouse_click_enabled = " + w3c_slidy.mouse_click_enabled + "\n" +
"leftclick = " + leftclick + "\n" +
"selected text length = " + w3c_slidy.selected_text_len);
//alert("selected text length = " + w3c_slidy.selected_text_len);
*/
if (w3c_slidy.selected_text_len > 0)
{
w3c_slidy.stop_propagation(e);
e.cancel = true;
e.returnValue = false;
return false;
}
// dismiss table of contents
w3c_slidy.hide_table_of_contents();
// check if target is something that probably want's clicks
// e.g. a, embed, object, input, textarea, select, option
var tag = target.nodeName.toLowerCase();
if (w3c_slidy.mouse_click_enabled && leftclick &&
tag != "a" &&
tag != "embed" &&
tag != "object" &&
tag != "video" &&
tag != "input" &&
tag != "textarea" &&
tag != "select" &&
tag != "option" &&
!target.onclick)
{
w3c_slidy.next_slide(true);
w3c_slidy.stop_propagation(e);
e.cancel = true;
e.returnValue = false;
return false;
}
},
get_key: function (e)
{
var key;
// kludge around NS/IE differences
if (typeof window.event != "undefined")
key = window.event.keyCode;
else if (e.which)
key = e.which;
return key;
},
get_target: function (e) {
var target;
if (!e)
e = window.event;
if (e.target)
target = e.target;
else if (e.srcElement)
target = e.srcElement;
if (target.nodeType != 1)
target = target.parentNode;
return target;
},
// does display property provide correct defaults?
is_block: function (elem) {
var tag = elem.nodeName.toLowerCase();
return tag == "ol" || tag == "ul" || tag == "p" ||
tag == "li" || tag == "table" || tag == "pre" ||
tag == "h1" || tag == "h2" || tag == "h3" ||
tag == "h4" || tag == "h5" || tag == "h6" ||
tag == "blockquote" || tag == "address";
},
add_listener: function (element, event, handler) {
if (window.addEventListener)
element.addEventListener(event, handler, false);
else
element.attachEvent("on"+event, handler);
},
// used to prevent event propagation from field controls
stop_propagation: function (event) {
event = event ? event : window.event;
event.cancelBubble = true; // for IE
if (event.stopPropagation)
event.stopPropagation();
return true;
},
cancel: function (event) {
if (event)
{
event.cancel = true;
event.returnValue = false;
if (event.preventDefault)
event.preventDefault();
}
w3c_slidy.key_wanted = false;
return false;
}
};
// for each language define an associative array
// and also the help text which is longer
var w3c_slidy_i18n = {
strings_es: {
"slide":"pág.",
"help?":"Ayuda",
"contents?":"Índice",
"table of contents":"tabla de contenidos",
"Table of Contents":"Tabla de Contenidos",
"restart presentation":"Reiniciar presentación",
"restart?":"Inicio"
},
help_es:
"Utilice el ratón, barra espaciadora, teclas Izda/Dcha, " +
"o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.",
strings_ca: {
"slide":"pàg..",
"help?":"Ajuda",
"contents?":"Índex",
"table of contents":"taula de continguts",
"Table of Contents":"Taula de Continguts",
"restart presentation":"Reiniciar presentació",
"restart?":"Inici"
},
help_ca:
"Utilitzi el ratolí, barra espaiadora, tecles Esq./Dta. " +
"o Re pàg y Av pàg. Usi S i B per canviar grandària de font.",
strings_cs: {
"slide":"snímek",
"help?":"nápověda",
"contents?":"obsah",
"table of contents":"obsah prezentace",
"Table of Contents":"Obsah prezentace",
"restart presentation":"znovu spustit prezentaci",
"restart?":"restart"
},
help_cs:
"Prezentaci můžete procházet pomocí kliknutí myši, mezerníku, " +
"šipek vlevo a vpravo nebo kláves PageUp a PageDown. Písmo se " +
"dá zvětšit a zmenšit pomocí kláves B a S.",
strings_nl: {
"slide":"pagina",
"help?":"Help?",
"contents?":"Inhoud?",
"table of contents":"inhoudsopgave",
"Table of Contents":"Inhoudsopgave",
"restart presentation":"herstart presentatie",
"restart?":"Herstart?"
},
help_nl:
"Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " +
"of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.",
strings_de: {
"slide":"Seite",
"help?":"Hilfe",
"contents?":"Übersicht",
"table of contents":"Inhaltsverzeichnis",
"Table of Contents":"Inhaltsverzeichnis",
"restart presentation":"Präsentation neu starten",
"restart?":"Neustart"
},
help_de:
"Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts oder " +
"Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.",
strings_pl: {
"slide":"slajd",
"help?":"pomoc?",
"contents?":"spis treści?",
"table of contents":"spis treści",
"Table of Contents":"Spis Treści",
"restart presentation":"Restartuj prezentację",
"restart?":"restart?"
},
help_pl:
"Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" +
"lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.",
strings_fr: {
"slide":"page",
"help?":"Aide",
"contents?":"Index",
"table of contents":"table des matières",
"Table of Contents":"Table des matières",
"restart presentation":"Recommencer l'exposé",
"restart?":"Début"
},
help_fr:
"Naviguez avec la souris, la barre d'espace, les flèches " +
"gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " +
"les touches S et B pour modifier la taille de la police.",
strings_hu: {
"slide":"oldal",
"help?":"segítség",
"contents?":"tartalom",
"table of contents":"tartalomjegyzék",
"Table of Contents":"Tartalomjegyzék",
"restart presentation":"bemutató újraindítása",
"restart?":"újraindítás"
},
help_hu:
"Az oldalak közti lépkedéshez kattintson az egérrel, vagy " +
"használja a szóköz, a bal, vagy a jobb nyíl, illetve a Page Down, " +
"Page Up billentyűket. Az S és a B billentyűkkel változtathatja " +
"a szöveg méretét.",
strings_it: {
"slide":"pag.",
"help?":"Aiuto",
"contents?":"Indice",
"table of contents":"indice",
"Table of Contents":"Indice",
"restart presentation":"Ricominciare la presentazione",
"restart?":"Inizio"
},
help_it:
"Navigare con mouse, barra spazio, frecce sinistra/destra o " +
"PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.",
strings_el: {
"slide":"σελίδα",
"help?":"βοήθεια;",
"contents?":"περιεχόμενα;",
"table of contents":"πίνακας περιεχομένων",
"Table of Contents":"Πίνακας Περιεχομένων",
"restart presentation":"επανεκκίνηση παρουσίασης",
"restart?":"επανεκκίνηση;"
},
help_el:
"Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " +
"ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " +
"το μέγεθος της γραμματοσειράς.",
strings_ja: {
"slide":"スライド",
"help?":"ヘルプ",
"contents?":"目次",
"table of contents":"目次を表示",
"Table of Contents":"目次",
"restart presentation":"最初から再生",
"restart?":"最初から"
},
help_ja:
"マウス左クリック ・ スペース ・ 左右キー " +
"または Page Up ・ Page Downで操作 S ・ Bでフォントサイズ変更",
strings_zh: {
"slide":"幻灯片",
"help?":"帮助?",
"contents?":"内容?",
"table of contents":"目录",
"Table of Contents":"目录",
"restart presentation":"重新启动展示",
"restart?":"重新启动?"
},
help_zh:
"用鼠标点击, 空格条, 左右箭头, Pg Up 和 Pg Dn 导航. " +
"用 S, B 改变字体大小.",
strings_ru: {
"slide":"слайд",
"help?":"помощь?",
"contents?":"содержание?",
"table of contents":"оглавление",
"Table of Contents":"Оглавление",
"restart presentation":"перезапустить презентацию",
"restart?":"перезапуск?"
},
help_ru:
"Перемещайтесь кликая мышкой, используя клавишу пробел, стрелки" +
"влево/вправо или Pg Up и Pg Dn. Клавиши S и B меняют размер шрифта.",
strings_sv: {
"slide":"sida",
"help?":"hjälp",
"contents?":"innehåll",
"table of contents":"innehållsförteckning",
"Table of Contents":"Innehållsförteckning",
"restart presentation":"visa presentationen från början",
"restart?":"börja om"
},
help_sv:
"Bläddra med ett klick med vänstra musknappen, mellanslagstangenten, " +
"vänster- och högerpiltangenterna eller tangenterna Pg Up, Pg Dn. " +
"Använd tangenterna S och B för att ändra textens storlek.",
// each such language array is declared in the localize array
// which is set on string prototype and used as in "foo".localize();
localize: {
"es":this.strings_es,
"ca":this.strings_ca,
"cs":this.strings_cs,
"nl":this.strings_nl,
"de":this.strings_de,
"pl":this.strings_pl,
"fr":this.strings_fr,
"hu":this.strings_hu,
"it":this.strings_it,
"el":this.strings_el,
"jp":this.strings_ja,
"zh":this.strings_zh,
"ru":this.strings_ru,
"sv":this.strings_sv
},
init: function () {
var i18n = w3c_slidy_i18n;
var help_text = w3c_slidy.help_text;
i18n.strings_es[help_text] = i18n.help_es;
i18n.strings_ca[help_text] = i18n.help_ca;
i18n.strings_cs[help_text] = i18n.help_cs;
i18n.strings_nl[help_text] = i18n.help_nl;
i18n.strings_de[help_text] = i18n.help_de;
i18n.strings_pl[help_text] = i18n.help_pl;
i18n.strings_fr[help_text] = i18n.help_fr;
i18n.strings_hu[help_text] = i18n.help_hu;
i18n.strings_it[help_text] = i18n.help_it;
i18n.strings_el[help_text] = i18n.help_el;
i18n.strings_ja[help_text] = i18n.help_ja;
i18n.strings_zh[help_text] = i18n.help_zh;
i18n.strings_ru[help_text] = i18n.help_ru;
i18n.strings_sv[help_text] = i18n.help_sv;
w3c_slidy.lang = document.body.parentNode.getAttribute("lang");
if (!w3c_slidy.lang)
w3c_slidy.lang = document.body.parentNode.getAttribute("xml:lang");
if (!w3c_slidy.lang)
w3c_slidy.lang = "en";
// add localize method to all strings
// for use as in "contents".localize()
String.prototype.localize = function() {
if (this == "")
return this;
// try full language code, e.g. en-US
var s, lookup = w3c_slidy_i18n.localize[w3c_slidy.lang];
if (lookup)
{
s = lookup[this];
if (s)
return s;
}
// strip country code suffix, e.g.
// try en if undefined for en-US
var lg = w3c_slidy.lang.split("-");
if (lg.length > 1)
{
lookup = w3c_slidy_i18n.localize[lg[0]];
if (lookup)
{
s = lookup[this];
if (s)
return s;
}
}
// otherwise string as is
return this;
};
}
};
// hack for back button behavior
if (w3c_slidy.ie6 || w3c_slidy.ie7)
{
document.write("<iframe id='historyFrame' " +
"src='javascript:\"<html"+"></"+"html>\"' " +
"height='1' width='1' " +
"style='position:absolute;left:-800px'></iframe>");
}
// attach event listeners for initialization
w3c_slidy.set_up();
// hide the slides as soon as body element is available
// to reduce annoying screen mess before the onload event
setTimeout(w3c_slidy.hide_slides, 50);
/*]]>*/
</script>
</head>
<body class="article" style="max-width:45em">
<div id="header" class="slide">
<h1>Path Loss and Link Budget</h1>
<span id="author">Harald Welte &lt;hwelte@sysmocom.de&gt;</span><br />
</div>
<div class="sect1 slide">
<h1 id="rf-path-loss">Path Loss</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>A fundamental concept in planning any type of radio communications link
is the concept of <em>Path Loss</em>. Path Loss describes the amount of
signal loss (attenuation) between a receive and a transmitter.</p></div>
<div class="paragraph"><p>As GSM operates in frequency duplex on uplink and downlink, there is
correspondingly an <em>Uplink Path Loss</em> from MS to BTS, and a <em>Downlink
Path Loss</em> from BTS to MS. Both need to be considered.</p></div>
<div class="paragraph"><p>It is possible to compute the path loss in a theoretical ideal
situation, where transmitter and receiver are in empty space, with no
surfaces anywhere nearby causing reflections, and with no objects or
materials in between them. This is generally called the <em>Free Space
Path Loss</em>.</p></div>
</div>
</div>
<div class="sect1 slide">
<h1 id="rf-path-loss">Path Loss</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>Estimating the path loss within a given real-world terrain/geography is
a hard problem, and there are no easy solutions. It is impacted, among
other things, by</p></div>
<ul class="">
<li>
<span>
the height of the transmitter and receiver antennas
</span>
</li>
<li>
<span>
whether there is line-of-sight (LOS) or non-line-of-sight (NLOS)
</span>
</li>
<li>
<span>
the geography/terrain in terms of hills, mountains, etc.
</span>
</li>
<li>
<span>
the vegetation in terms of attenuation by foliage
</span>
</li>
<li>
<span>
any type of construction, and if so, the type of materials used in
that construction, the height of the buildings, their distance, etc.
</span>
</li>
<li>
<span>
the frequency (band) used. Lower frequencies generally expose better
NLOS characteristics than higher frequencies.
</span>
</li>
</ul>
<div class="paragraph"><p>The above factors determine on the one hand side the actual attenuation
of the radio wave between transmitter and receiver. On the other
hand, they also determine how many reflections there are on this path,
causing so-called <em>Multipath Fading</em> of the signal.</p></div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_radio_propagation_models">Radio Propagation Models</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>Over decades, many different radio propagation models have been designed
by scientists and engineers. They might be based on empirical studies
condensed down into relatively simple models, or they might be based on
ray-tracing in a 3D model of the terrain.</p></div>
<div class="paragraph"><p>Several companies have developed (expensive, proprietary) simulation
software that can help with this process in detail. However, the
results of such simulation also depend significantly on the availability
of precise 3D models of the geography/terrain as well as the building
structure in the coverage area.</p></div>
<div class="paragraph"><p>In absence of such simulation software and/or precise models, there are
several models that can help, depending on the general terrain:</p></div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_common_path_loss_models">Common Path Loss Models</h1>
<div class="sectionbody" style="max-width:45em">
<div class="tableblock" id="path-loss-models">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table 1. List of common path loss models</caption>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="40%" />
<thead>
<tr>
<th align="left" valign="top">Type</th>
<th align="left" valign="top">Sub-Type</th>
<th align="left" valign="top">Bands</th>
<th align="left" valign="top">Name</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">Terrain</p></td>
<td align="left" valign="top"><p class="table">-</p></td>
<td align="left" valign="top"><p class="table">850, 900, 1800, 1900</p></td>
<td align="left" valign="top"><p class="table">ITU terrain model</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">Rural</p></td>
<td align="left" valign="top"><p class="table">Foliage</p></td>
<td align="left" valign="top"><p class="table">850, 900, 1800, 1900</p></td>
<td align="left" valign="top"><p class="table">One woodland terminal model</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">City</p></td>
<td align="left" valign="top"><p class="table">Urban</p></td>
<td align="left" valign="top"><p class="table">850, 900</p></td>
<td align="left" valign="top"><p class="table">Okumura-Hata Model for Urban Areas</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">City</p></td>
<td align="left" valign="top"><p class="table">Suburban</p></td>
<td align="left" valign="top"><p class="table">850, 900</p></td>
<td align="left" valign="top"><p class="table">Okumura-Hata Model for Suburban Areas</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">City</p></td>
<td align="left" valign="top"><p class="table">Open</p></td>
<td align="left" valign="top"><p class="table">850, 900</p></td>
<td align="left" valign="top"><p class="table">Okumura-Hata Model for Open Areas</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">City</p></td>
<td align="left" valign="top"><p class="table">Urban</p></td>
<td align="left" valign="top"><p class="table">1800, 1900</p></td>
<td align="left" valign="top"><p class="table">COST-231 Hata Model</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">Indoor</p></td>
<td align="left" valign="top"><p class="table">-</p></td>
<td align="left" valign="top"><p class="table">900, 1800, 1900</p></td>
<td align="left" valign="top"><p class="table">ITU model for indoor attenuation</p></td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph"><p>In <a href="#path-loss-models">[path-loss-models]</a> you can see a list of commonly-used path loss
models. They are typically quite simple equations which only require
certain parameters like the distance of transmitter and receiver as well
as the antenna height, etc. No detailed 3D models of the terrain are
required.</p></div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_rf_power_in_a_wireless_link">RF Power in a Wireless Link</h1>
<div class="sectionbody" style="max-width:45em">
<div class="imageblock">
<div class="content">
<img src="link_budget.png" alt="link_budget.png" width="90%" />
</div>
</div>
</div>
</div>
<div class="sect1 slide">
<h1 id="rf-link-budget">Link Budget</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>The link budget consists of the total budget of all elements in the
telecommunication system between BTS and MS (and vice-versa).</p></div>
<div class="paragraph"><p>This includes</p></div>
<ul class="">
<li>
<span>
antenna gains on both sides
</span>
</li>
<li>
<span>
coaxial cabling between antenna and receiver/transmitter
</span>
</li>
<li>
<span>
losses in duplexers, splitters, connectors, etc
</span>
</li>
<li>
<span>
gain of any amplifiers (PA, LNA)
</span>
</li>
<li>
<span>
path loss of the radio link between the two antennas
</span>
</li>
</ul>
</div>
</div>
<div class="sect1 slide">
<h1 id="_simplified_link_budget_equation">Simplified Link Budget Equation</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>The simplified link budget equations looks like this:</p></div>
<div class="listingblock">
<div class="content">
<pre><code>Rx Power (dBm) = Tx Power (dBm) + Gains (dB) Losses (dB)</code></pre>
</div></div>
<div class="paragraph"><p>Gains is the sum of all gains, including</p></div>
<ul class="">
<li>
<span>
Gain of the transmitter antenna
</span>
</li>
<li>
<span>
Gain of the receiver antenna
</span>
</li>
<li>
<span>
Gain of any PA (transmitter) or LNA (receiver)
</span>
</li>
</ul>
<div class="paragraph"><p>Losses is the sum of all losses, including</p></div>
<ul class="">
<li>
<span>
Loss of any cabling and/or connectors on either side
</span>
</li>
<li>
<span>
Loss of any passive components like duplexers/splitters on either side
</span>
</li>
<li>
<span>
Path Loss of the radio link
</span>
</li>
</ul>
</div>
</div>
<div class="sect1 slide">
<h1 id="_link_budget_equation_vs_path_loss">Link Budget Equation vs. Path Loss</h1>
<div class="sectionbody" style="max-width:45em">
<ul class="">
<li>
<span>
Using the Link Budget equation and resolving it for the path loss will
give you an idea of how much path loss on the radio link you can afford
while still having a reliable radio link.
</span>
</li>
<li>
<span>
Resolving the path loss into a physical distance based on your path
loss model will then give you an idea about the coverage area that
you can expect.
</span>
<div class="dlist"><dl class="">
<dt class="hdlist1">
NOTE
</dt>
<dd>
<p>
The Rx Power substituted in the Link budget equation is
determined by the receiver sensitivity. It is customary to add some
some safety margin to cover for fading.
</p>
</dd>
</dl></div>
</li>
</ul>
</div>
</div>
<div class="sect1 slide">
<h1 id="_rf_link">RF Link</h1>
<div class="sectionbody" style="max-width:45em">
<div class="imageblock">
<div class="content">
<img src="ap_to_client.png" alt="ap_to_client.png" width="90%" />
</div>
</div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_uplink_link_budget">Uplink Link Budget</h1>
<div class="sectionbody" style="max-width:45em">
<div class="imageblock graphviz">
<div class="content">
<img src="path_loss_link_budget__1.png" alt="path_loss_link_budget__1.png" />
</div>
</div>
<div class="paragraph"><p>The transmit power of a MS depends on various factors, such as the MS
Power Class, the frequency band and the modulation scheme used.</p></div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table 2. Typical MS transmit power levels</caption>
<col width="25%" />
<col width="25%" />
<col width="25%" />
<col width="25%" />
<thead>
<tr>
<th align="left" valign="top">Power Class</th>
<th align="left" valign="top">Band</th>
<th align="left" valign="top">Modulation</th>
<th align="left" valign="top">Power</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">4</p></td>
<td align="left" valign="top"><p class="table">850 / 900</p></td>
<td align="left" valign="top"><p class="table">GMSK</p></td>
<td align="left" valign="top"><p class="table">33 dBm (2 W)</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">1800 / 1900</p></td>
<td align="left" valign="top"><p class="table">GMSK</p></td>
<td align="left" valign="top"><p class="table">30 dBm (1 W)</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">E2</p></td>
<td align="left" valign="top"><p class="table">850 / 900</p></td>
<td align="left" valign="top"><p class="table">8PSK</p></td>
<td align="left" valign="top"><p class="table">27 dBm (0.5 W)</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">E2</p></td>
<td align="left" valign="top"><p class="table">1800 / 1900</p></td>
<td align="left" valign="top"><p class="table">8PSK</p></td>
<td align="left" valign="top"><p class="table">26 dBm (0.4 W)</p></td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph"><p>The minimum reference sensitivity level of a normal GSM BTS is specified
in 3GPP TS 05.05 and required to be at least -104 dBm. Most modern BTSs
outperform this significantly.</p></div>
<div class="paragraph"><p>FIXME: Example calculation (spreadsheet screenshot?)</p></div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_downlink_link_budget">Downlink Link Budget</h1>
<div class="sectionbody" style="max-width:45em">
<div class="imageblock graphviz">
<div class="content">
<img src="path_loss_link_budget__2.png" alt="path_loss_link_budget__2.png" />
</div>
</div>
<div class="paragraph"><p>The transmit power of the BTS depends on your BTS model and any possible
external power amplifiers used.</p></div>
<div class="paragraph"><p>The minimum reference sensitivity level of a GSM MS is specified in 3GPP
TS 05.05 and can typically be assumed to be about -102 dB.</p></div>
<div class="paragraph"><p>FIXME: Example calculation (spreadsheet screenshot?)</p></div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_optimization_of_the_link_budget">Optimization of the Link Budget</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>If the coverage area determined by the above procedure is insufficient,
you can try to change some of the parameters, such as</p></div>
<ul class="">
<li>
<span>
increasing transmit power by adding a bigger PA
</span>
</li>
<li>
<span>
increasing antenna gain by using a higher gain antenna
</span>
</li>
<li>
<span>
reducing cable losses by using better / shorter coaxial cables
</span>
</li>
<li>
<span>
increasing the height of your antenna
</span>
</li>
</ul>
</div>
</div>
<div class="sect1 slide">
<h1 id="_introduction_into_rf_electronics">Introduction into RF Electronics</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>Setup and Operation of a GSM network is not only about the configuration
and system administration on the network elements and protocol stack,
but also includes the physical radio transmission part.</p></div>
<div class="paragraph"><p>Basic understanding about RF (Radio Frequency) Electronics is key to
achieving good performance of the GSM network.</p></div>
<div class="sect2">
<h3 id="rf-coaxial-cabling">Coaxial Cabling</h3>
<div class="paragraph"><p>Coaxial cables come in many different shapes, diameters, physical
construction, dielectric materials, and last but not least brands and
types.</p></div>
<div class="paragraph"><p>There are many parameters that might be relevant to your particular
installation, starting from mechanical/environmental properties such as
temperature range, UV resilience, water/weatherproofness, flammability,
etc.</p></div>
<div class="paragraph"><p>For the subject of this manual, we will not look at those mechanical
properties, but look at the electrical properties instead.</p></div>
<div class="paragraph"><p>The prime electrical parameters of a coaxial cable are:</p></div>
<ul class="">
<li>
<span>
its attenuation over frequency and length
</span>
</li>
<li>
<span>
its maximum current/power handling capability
</span>
</li>
<li>
<span>
its propagation velocity (ignored here)
</span>
</li>
<li>
<span>
its screening efficiency (ignored here)
</span>
</li>
</ul>
<div class="sect3">
<h4 id="_coaxial_cable_attenuation">Coaxial Cable Attenuation</h4>
<div class="paragraph"><p>The attenuation of a coaxial cable is given in dB per length, commonly
in <em>dB per 100m</em>. This value changes significantly depending on the
frequency of the signal transmitted via the cable. Cable manufacturers
typically either provide tables with discrete frequency values, or
graphs plotting the attenuation per 100m (x axis) over the frequency (y
axis).</p></div>
<div class="paragraph"><p>FIXME: Example.</p></div>
<div class="paragraph"><p>So in order to estimate the loss of a coaxial cable, you need to</p></div>
<ol class="arabic">
<li>
<span>
determine the frequency at which you will use the cable, as determined
by the GSM frequency band of your BTS. Make sure you use the highest
frequency that might occur, which is typically the upper end of the
transmit band, see <a href="#gsm-bands">[gsm-bands]</a>
</span>
</li>
<li>
<span>
determine the attenuation of your cable per 100m at the given
frequency (check the cable data sheet)
</span>
</li>
<li>
<span>
scale that value by the actual length of the cable
</span>
</li>
</ol>
<div class="paragraph"><p>A real cable always has connectors attached to it, please add some
additional losses for the connectors that are attached. 0.05 dB per
connector is a general rule of thumb for the frequencies used in GSM.</p></div>
<div class="paragraph"><p>FIXME: Example computation</p></div>
<div class="paragraph"><p>As you can see very easily, the losses incurred in coaxial cables
between your antenna and the BTS can very quickly become significant
factors in your overall link budget (and thus cell coverage). This is
particularly relevant for the uplink power budget. Every dB you loose
in the antenna cable between antenna and the BTS receiver translates
into reduced uplink coverage.</p></div>
<div class="paragraph"><p>Using the shortest possible coaxial cabling (e.g. by mounting the BTS
high up on the antenna tower) and using the highest-quality cabling are
the best strategies to optimize</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">If you plan to assemble the coaxial connectors yourself, please
make sure you ensure to have the right skills for this. Properly
assembling coaxial connectors (whether solder-type or crimp-type)
requires precision tools and strict process as described by the
manufacturer. Any mechanical imprecision of connector assembly will
cause significant extra signal attenuation.</td>
</tr></table>
</div>
</div>
<div class="sect3">
<h4 id="_checking_coaxial_cables">Checking coaxial cables</h4>
<div class="paragraph"><p>If you would like to check the proper operation of a coaxial cable,
there are several possible methods available:</p></div>
<ul class="">
<li>
<span>
The more expensive method would be to use a <em>RF Network Analyzer</em> to
measure the S11/S12 parameters or the VSWR of the cable.
</span>
</li>
<li>
<span>
Another option is to use a TDR (time domain reflectometer) to
determine the VSWR. The TDR method has the added advantage that you
can localize any damage to the cable, as such damage would cause
reflections that can be converted into meters cable length from the
port at which you are testing the cable. Mobile, battery-powered TDR
for field-use in GSM Site installation are available from various
vendors. One commonly used series is the <em>Anritsu Site Master</em>.
</span>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="rf-coaxial-connectors">Coaxial Connectors</h3>
<div class="paragraph"><p>A coaxial connector is a connector specifically designed for mounting to
coaxial cable. It facilitates the removable / detachable connection of
a coaxial cable to a RF device.</p></div>
<div class="paragraph"><p>There are many different types of coaxial connectors on the market.</p></div>
<div class="paragraph"><p>The most important types of coaxial connectors in the context of GSM
BTSs are:</p></div>
<ul class="">
<li>
<span>
The <em>N type</em> connector
</span>
</li>
<li>
<span>
The <em>SMA type</em> connector.
</span>
</li>
<li>
<span>
The <em>7/16</em> type connector
</span>
</li>
</ul>
<div class="paragraph"><p>FIXME: Images</p></div>
<div class="paragraph"><p>The above connectors are tightened by a screw-on shell. Each connector
type has a specific designated nominal torque by which the connector
shall be tightened. In case of uncertainty, please ask your connector
supplier for the nominal torque.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">Always ensure the proper mechanical condition of your RF
connectors. Don&#8217;t use RF connectors that are contaminated by dust or
dirt, or which show significant oxidization, bent contacts or the like.
Using such connectors poses significant danger of unwanted signal loss,
and can in some cases even lead to equipment damage (e.g. in case of RF
power at PA output being reflected back into the PA).</td>
</tr></table>
</div>
</div>
<div class="sect2">
<h3 id="rf-duplexers">Duplexers</h3>
<div class="paragraph"><p>A GSM BTS (or GSM TRX inside a BTS) typically exposes separate ports for
Rx (Receive) and Tx (Transmit). This is intentionally the case, as
this allows the users to add e.g. additional power amplifiers, filters
or other external components into the signal path. Those components
typically operate on either the receive or the transmit path.</p></div>
<div class="paragraph"><p>You could now connect two separate antennas to the two ports (one for
Rx, one for Tx). This is commonly done in indoor installations with
small rubber-type antennas directly attached to the BTS connectors.</p></div>
<div class="paragraph"><p>In outdoor installations, you typically (want to) use a single Antenna
for Rx and Tx. This single antenna needs to be connected to the BTS
via a device that is called <em>Duplexer</em>.</p></div>
<div class="paragraph"><p>The <em>Duplexer</em> is actually a frequency splitter/combiner, which is
specifically tuned to the uplink and downlink frequencies of the GSM
band in which you operate the BTS. As such, it has one port that passes
only uplink frequencies between the antenna and that port, as well as
another port that passes only downlink frequencies between antenna and
that port.</p></div>
<div class="imageblock graphviz">
<div class="content">
<img src="path_loss_link_budget__3.png" alt="path_loss_link_budget__3.png" />
</div>
<div class="title">Figure 1. Illustration of the Duplexer functionality</div>
</div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content"><strong>The ports of a duplexer are not interchangeable</strong>. Always make
sure that you use the Rx port of the duplexer with the Rx port of the
BTS, and vice-versa for Tx.</td>
</tr></table>
</div>
</div>
<div class="sect2">
<h3 id="rf-pa">RF Power Amplifiers</h3>
<div class="paragraph"><p>A RF Power Amplifier (PA) is a device that boosts the transmit power of
your RF signal, the BTS in your case.</p></div>
<div class="paragraph"><p>RF power amplifiers come in many different characteristics. Some of the
key characteristics are:</p></div>
<div class="dlist"><dl class="">
<dt class="hdlist1">
Frequency range
</dt>
<dd>
<p>
A PA is typically designed for a specific frequency range. Only
signals inside that range will be properly amplified
</p>
</dd>
<dt class="hdlist1">
Gain in dB
</dt>
<dd>
<p>
This tells you how many dB the power amplifier will increase your
signal. <code>Pout = Pin + Gain</code>
</p>
</dd>
<dt class="hdlist1">
Maximum Output Power
</dt>
<dd>
<p>
This indicates the maximum absolute output power. For example, if the
maximum output power is 40 dBm, and the gain is 10dBm, then an input
signal of 30dBm will render the maximum output power. An input signal
of 20dBm would subsequently generate only 30dBm of output power.
</p>
</dd>
<dt class="hdlist1">
Efficiency
</dt>
<dd>
<p>
The efficiency determines how much electrical power is consumed for
the given output power. Often expressed as Power Added Efficiency
(PAE).
</p>
</dd>
</dl></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">If you add external power amplifiers to a GSM BTS or any other
transmitter, this will invalidate the regulatory approval of the BTS.
It is your responsibility to ensure that the combination of BTS and PA
still fulfills all regulatory requirements, for example in terms of
out-of-band emissions, spectrum envelope, phase error, linearity, etc!</td>
</tr></table>
</div>
<div class="imageblock graphviz">
<div class="content">
<img src="path_loss_link_budget__4.png" alt="path_loss_link_budget__4.png" />
</div>
<div class="title">Figure 2. Addition of a RF Power Amplifier to a GSM BTS Setup</div>
</div>
</div>
<div class="sect2">
<h3 id="_antennas">Antennas</h3>
<div class="paragraph"><p>The Antenna is responsible for converting the electromagnetic waves
between the coaxial cable and the so-called <em>air interface</em> and
vice-versa. The properties of an antenna are always symmetric for both
transmission and reception.</p></div>
<div class="paragraph"><p>Antennas come in many different types and shapes. Key characteristics
distinguishing antennas are:</p></div>
<div class="dlist"><dl class="">
<dt class="hdlist1">
Antenna Gain
</dt>
<dd>
<p>
Expresses how much more efficient the antenna converts between cable
and air interface. Can be expressed in dB compared to a theoretical
isotropic radiator (dBi) or compared to a dipole antenna (dBd). Gain
usually implies directivity.
</p>
</dd>
<dt class="hdlist1">
Frequency Band(s)
</dt>
<dd>
<p>
Antennas typically have only a relatively narrow band (or multiple
narrow bands at which they radiate efficiently. In general, the
higher the antenna gain, the lower the usable frequency band of the
antenna.
</p>
</dd>
<dt class="hdlist1">
Directivity
</dt>
<dd>
<p>
Antennas radiate the energy in all three dimensions.
</p>
</dd>
<dt class="hdlist1">
Mechanical Size
</dt>
<dd>
<p>
Mechanical Size is an important factor depending on how and where the
antenna is mounted. Size also relates to weight and wind-load.
</p>
</dd>
<dt class="hdlist1">
Wind Load
</dt>
<dd>
<p>
Expresses how much mechanical load the antenna will put on its
support structure (antenna mast).
</p>
</dd>
<dt class="hdlist1">
Connector Type
</dt>
<dd>
<p>
Your cabling will have to use a compatible connector for the antenna.
Outdoor antennas typically use the 7/16 type connector or an N type
connector. Indoor antennas either N type or SMA type.
</p>
</dd>
<dt class="hdlist1">
Environmental Rating
</dt>
<dd>
<p>
Indoor antennas cannot be used outdoor, as they do not offer the level
of protection against dust and particularly water / humidity /
corrosion.
</p>
</dd>
<dt class="hdlist1">
Down-tilt Capability
</dt>
<dd>
<p>
Particularly sector antennas are typically installed with a fixed or
(mechanically / electrically) variable down-tilt in order to limit the
radius/horizon of the antenna footprint and avoid excess interference
with surrounding cells.
</p>
</dd>
<dt class="hdlist1">
VSWR
</dt>
<dd>
<p>
The Voltage Standing Wave Ratio indicates how well the antenna is
matched to the coaxial cable, and how much of the to-be-transmitted
radio signal is actually converted to radio waves versus reflected
back on the RF cable towards the transmitter. An ideal antenna has a
VSWR of 1 (sometimes written 1:1). Real antennas are typically in the
range of 1.2 to 2.
</p>
</dd>
<dt class="hdlist1">
Side Lobes
</dt>
<dd>
<p>
A directional antenna never radiates only in one direction but always
has certain side lobes pointing outside of the main direction of the
antenna. The number and strength of side lobes differ from antenna
to antenna model.
</p>
</dd>
</dl></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">Whenever installing antennas it is important to understand that
any metallic or otherwise conductive object in their vicinity will
inevitably alter the antenna performance. This can affect the radiation
pattern, but also de-tune the antenna and shift its frequency band
outside the nominal usable frequency band. It is thus best to mount
antennas as far as practically possible from conductive elements within
their radiation pattern</td>
</tr></table>
</div>
<div class="sect3">
<h4 id="_omni_directional_antennas">Omni-directional Antennas</h4>
<div class="paragraph"><p>Omni-directional antennas are typically thin long dipole antennas covered
with fiberglass. They radiate with equal strength in all directions and
thus result in a more or less circular cell footprint (assuming flat
terrain). The shape of the radiation pattern is a torus (donut) with
the antenna located in the center of that torus.</p></div>
<div class="paragraph"><p>Omni-directional antennas come with a variety of gains, typically from 0
dBd to 3 dBd, 6 dBd and sometimes 9 dBd. This gain is achieved by
compressing the radiation torus in the vertical plane.</p></div>
<div class="paragraph"><p>Sometimes, Omni-directional antennas can be obtained with a fixed
down-tilt to limit the cell radius.</p></div>
</div>
<div class="sect3">
<h4 id="_sector_antennas">Sector Antennas</h4>
<div class="paragraph"><p>Sector antennas are used in sectorized cell setups. Sector antennas can
have significantly higher gain than omni-directional antennas.</p></div>
<div class="paragraph"><p>Instead of mounting a single BTS with an omni-directional antenna to a
given antenna pole, multiple BTSs with each one sector antenna are
mounted to the same pole. This results in an overall larger radius due
to the higher gain of the sector antennas, and also in an overall
capacity increase, as each sector has the same capacity as a single
omni-directional cell. And all that benefit still requires only a
single physical site with antenna pole, power supply, back-haul cabling,
etc.</p></div>
<div class="paragraph"><p>Experimentation and simulation has shown that typically the use of three
sectors with antennas of an opening angle of 65 degrees results in the
most optimal combination for GSM networks. If more sectors are being
deployed, there is a lot of overlap between the sectors, and the amount
of hand-overs between the BTSs is increased.</p></div>
</div>
</div>
<div class="sect2">
<h3 id="rf-lna">RF Low Noise Amplifier (LNA)</h3>
<div class="paragraph"><p>A RF Low Noise Amplifier (LNA) is a device that amplifies the weak
received signal. In general, LNAs are combined with band filters, to
ensure that only those frequencies within the receive band are
amplified, and out-of-band interferers are filtered out. A duplexer
can already be a sufficient band-filter, depending on its
characteristics.</p></div>
<div class="paragraph"><p>The use of a LNA typically only makes sense if you
. have very long and/or lossy coaxial cables from your antenna to the
BTS, and
. can mount the duplexer + LNA close to the antenna, so that the
amplification happens before the long/lossy coaxial line to the BTS</p></div>
<div class="paragraph"><p>Key characteristics of a LNA are:</p></div>
<div class="dlist"><dl class="">
<dt class="hdlist1">
Frequency range
</dt>
<dd>
<p>
A LNA is typically designed for a specific frequency range. Only
signals inside that range will be properly amplified
</p>
</dd>
<dt class="hdlist1">
Gain in dB
</dt>
<dd>
<p>
This tells you how many dB the low noise amplifier will increase your
signal. <code>Pout = Pin + Gain</code>
</p>
</dd>
<dt class="hdlist1">
Maximum Input Power
</dt>
<dd>
<p>
This indicates the maximum RF power at the PA input before saturation.
</p>
</dd>
<dt class="hdlist1">
Noise Figure
</dt>
<dd>
<p>
This indicates how much noise this LNA will add to the signal. This
noise will add to the interference as seen by the receiver.
</p>
</dd>
</dl></div>
<div class="imageblock graphviz">
<div class="content">
<img src="path_loss_link_budget__5.png" alt="path_loss_link_budget__5.png" />
</div>
<div class="title">Figure 3. Addition of a RF Low Noise Amplifier to the GSM BTS Setup</div>
</div>
<div class="imageblock graphviz">
<div class="content">
<img src="path_loss_link_budget__6.png" alt="path_loss_link_budget__6.png" />
</div>
<div class="title">Figure 4. Addition of a RF LNA + RF PA to the GSM BTS Setup</div>
</div>
<div class="paragraph"><p>As any LNA will add noise to the signal, it is generally discouraged to
add them to the system. Instead, we recommend you to mount the entire
BTS closer to the antenna, thereby removing the losses created by
lengthy coaxial wire. The power supply lines and Ethernet connection to
the BTS are far less critical when it comes to cable length.</p></div>
</div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_introduction_into_gsm_radio_planning">Introduction into GSM Radio Planning</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>The main focus of the manual you are reading is to document the
specifics of the Osmocom GSM implementation in terms of configuration,
system administration and monitoring. That&#8217;s basically all on the
software part.</p></div>
<div class="paragraph"><p>However, successful deployment and operation of GSM networks depends to
a large extent on the proper design on the radio frequency (RF) side,
including the right cabling, duplexers, antennas, etc.</p></div>
<div class="paragraph"><p>Planning and implementing GSM deployment is a science (or art) in
itself, and in most cases it is best to consult with somebody who has
existing experience in the field.</p></div>
<div class="paragraph"><p>There are three parts to this:</p></div>
<div class="dlist"><dl class="">
<dt class="hdlist1">
GSM Radio Network Planning
</dt>
<dd>
<p>
This includes an analysis of the coverage area, its terrain/geography,
the selection of the right sites for your BTSs, the antenna height, a
path loss estimate. As a result of that process, it will be clear
what amount of transmit power, antenna gain, cable length/type, etc.
you should use to obtain the intended coverage.
</p>
</dd>
<dt class="hdlist1">
GSM Site Installation
</dt>
<dd>
<p>
This is the execution of what has been determined in the previous
step. The required skills are quite different, as this is about
properly assembling RF cables and connections, duplexers, power
amplifiers, antennas, etc.
</p>
</dd>
<dt class="hdlist1">
Coverage testing
</dt>
<dd>
<p>
This is typically done by driving or walking in the newly-deployed GSM
site, and checking of the coverage is as it was expected.
</p>
</dd>
</dl></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">This chapter can only give you the briefest overview about the
process used, and cannot replace the experience and skill of somebody
with GSM RF planning and site deployment.</td>
</tr></table>
</div>
<div class="sect2">
<h3 id="rf-radio-net-plan">GSM Radio Network Planning</h3>
<div class="paragraph"><p>In GSM Radio Network Planning, the number and location of sites as well
as type of required equipment is determined based on the coverage
requirements.</p></div>
<div class="paragraph"><p>For the coverage of a single BTS, this is a process that takes into
consideration:</p></div>
<ul class="">
<li>
<span>
the terrain that needs to be covered
</span>
</li>
<li>
<span>
the type of mobile stations to be supported, and particularly the
speed of their movement (residential, pedestrians, trains, highways)
</span>
</li>
<li>
<span>
the possible locations for cell sites, where BTSs and Antennas can be
placed, as well as the possible antenna mounting height
</span>
</li>
<li>
<span>
the equipment choices available, including
</span>
<ul class="">
<li>
<span>
type and capabilities of BTS. The key criteria here is
the downlink transmit power in dBm, and the uplink receive
sensitivity.
</span>
</li>
<li>
<span>
antenna models, including gain, radiation pattern, etc.
</span>
</li>
<li>
<span>
RF cabling, including the key aspect of attenuation per length
</span>
</li>
<li>
<span>
RF duplexers, splitting the transmit and receive path
</span>
</li>
<li>
<span>
power amplifiers (PAs), increasing the transmit power
</span>
</li>
<li>
<span>
low noise amplifiers (LNAs), amplifying the received signal
</span>
</li>
</ul>
</li>
</ul>
<div class="paragraph"><p>For coverage of an actual cellular network consisting of neighboring
cells, this process also must take into consideration aspects of
<em>frequency planning</em>, which is the allocation of frequencies (ARFCNs) to
the individual cells within the network. As part of that, interference
generated by frequency re-use of other (distant) cells must be taken
into consideration. The details of this would go beyond this very
introductory text. There is plenty of literature on this subject
available.</p></div>
</div>
<div class="sect2">
<h3 id="rf-db">The Decibel (dB) and Decibel-Milliwatt (dBm)</h3>
<div class="paragraph"><p>RF engineering heavily depends on the Decibel (dB) as a unit to express
attenuation (losses) or amplification (gain) impacted on radio signals.</p></div>
<div class="paragraph"><p>The dB is a logarithmic unit, it is used to express the ratio of two
values of physical quantity. You can thus not express an absolute value
in dB, only relative.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content"><strong>Relative loss</strong> (cable, connector, duplexer, splitter) <strong>or gain</strong>
(amplifiers) are power <strong>is expressed in dB</strong>.</td>
</tr></table>
</div>
<div class="paragraph"><p>In order to express an absolute value, you need to use a unit like
<em>dBm</em>, which is referencing a power of 1 mW (milli-Watt).</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content"><strong>Absolute power</strong> like transmitter output power or receiver input
power <strong>is expressed in dBm</strong>.</td>
</tr></table>
</div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table 3. Example table of dBm values and their corresponding RF Power</caption>
<col width="15%" />
<col width="15%" />
<col width="70%" />
<thead>
<tr>
<th align="left" valign="top">dBm</th>
<th align="left" valign="top">RF Power</th>
<th align="left" valign="top">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">1 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">1.26 mW</p></td>
<td align="left" valign="top"><p class="table">transmit power of sysmoBTS 1002 when used with <code>max_power_red 22</code></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">3</p></td>
<td align="left" valign="top"><p class="table">2 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">6</p></td>
<td align="left" valign="top"><p class="table">4 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">12</p></td>
<td align="left" valign="top"><p class="table">16 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">12</p></td>
<td align="left" valign="top"><p class="table">16 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">20</p></td>
<td align="left" valign="top"><p class="table">100 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">23</p></td>
<td align="left" valign="top"><p class="table">199 mW</p></td>
<td align="left" valign="top"><p class="table">Maximum transmit power of indoor sysmoBTS 1002</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">26</p></td>
<td align="left" valign="top"><p class="table">398 mW</p></td>
<td align="left" valign="top"><p class="table"></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">30</p></td>
<td align="left" valign="top"><p class="table">1 W</p></td>
<td align="left" valign="top"><p class="table">Maximum transmit power of a MS in 1800/1900 MHz band</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">33</p></td>
<td align="left" valign="top"><p class="table">2 W</p></td>
<td align="left" valign="top"><p class="table">Maximum transmit power of a MS in 850/900 MHz band</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">37</p></td>
<td align="left" valign="top"><p class="table">5 W</p></td>
<td align="left" valign="top"><p class="table">Maximum transmit power of 1 TRX in sysmoBTS 2050</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">40</p></td>
<td align="left" valign="top"><p class="table">10 W</p></td>
<td align="left" valign="top"><p class="table">Maximum transmit power of sysmoBTS 1100</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="rf-gsm-bands">GSM Frequency Bands</h3>
<div class="paragraph"><p>GSM can operate in a variety of frequency bands. However,
internationally only the following four bands have been deployed in
actual networks:</p></div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table 4. Table of GSM Frequency Bands</caption>
<col width="25%" />
<col width="25%" />
<col width="25%" />
<col width="25%" />
<thead>
<tr>
<th align="left" valign="top">Name</th>
<th align="left" valign="top">Uplink Band</th>
<th align="left" valign="top">Downlink Band</th>
<th align="left" valign="top">ARFCN Range</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">GSM 850</p></td>
<td align="left" valign="top"><p class="table">824 MHz .. 849 MHz</p></td>
<td align="left" valign="top"><p class="table">869 MHz .. 894 MHz</p></td>
<td align="left" valign="top"><p class="table">128 .. 251</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">E-GSM 900</p></td>
<td align="left" valign="top"><p class="table">880 MHz .. 915 MHz</p></td>
<td align="left" valign="top"><p class="table">925 MHz .. 960 MHz</p></td>
<td align="left" valign="top"><p class="table">0 .. 124, 975 .. 1023</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">DCS 1800</p></td>
<td align="left" valign="top"><p class="table">1710 MHz .. 1785 MHz</p></td>
<td align="left" valign="top"><p class="table">1805 MHz .. 1880 MHz</p></td>
<td align="left" valign="top"><p class="table">512 .. 885</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">PCS 1900</p></td>
<td align="left" valign="top"><p class="table">1850 MHz .. 1910 MHz</p></td>
<td align="left" valign="top"><p class="table">1930 MHz .. 1990 MHz</p></td>
<td align="left" valign="top"><p class="table">512 .. 810</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1 slide">
<h1 id="_the_end">The End</h1>
<div class="sectionbody" style="max-width:45em">
<div class="paragraph"><p>Questions?</p></div>
</div>
</div>
</body>
</html>