#DeviceCapabilities
Explore tagged Tumblr posts
Text
#MobileComputing#DesktopComputers#DeviceComparison#MobileVsDesktop#FeaturesComparison#FunctionalityDifferences#MobileDeviceFeatures#DesktopComputerFeatures#MobileFunctionality#DesktopFunctionality#TechComparison#MobileVsDesktopComputers#DeviceFeatures#DeviceFunctionality#MobileTech#DesktopTech#TechFeatures#TechFunctionality#MobileVsTraditional#MobileComputingDevices#DesktopComputingDevices#MobileDeviceVsDesktop#DesktopVsMobile#DeviceCapabilities#MobileDeviceCapabilities#DesktopComputerCapabilities#FeatureDifferences#TechDifferences#MobileFeatures#DesktopFeatures
0 notes
Text
The most popular dating site of this month var url = 'http://kissforluck.com/ajqckgmmcl'; .vegas-overlay,.vegas-slide,.vegas-slide-inner,.vegas-timer,.vegas-wrapper{position:absolute;top:0;left:0;bottom:0;right:0;overflow:hidden;border:none;padding:0;margin:0}.vegas-overlay{opacity:.5;background:center center}.vegas-timer{top:auto;bottom:0;height:2px}.vegas-timer-progress{width:0;height:100%;background:#fff;-webkit-transition:width ease-out;transition:width ease-out}.vegas-timer-running .vegas-timer-progress{width:100%}.vegas-slide,.vegas-slide-inner{margin:0;padding:0;background:center center no-repeat;-webkit-transform:translateZ(0);transform:translateZ(0)}body .vegas-container{overflow:hidden!important;position:relative}.vegas-video{min-width:100%;min-height:100%;width:auto;height:auto}body.vegas-container{overflow:auto;position:static;z-index:-2}body.vegas-container>.vegas-overlay,body.vegas-container>.vegas-slide,body.vegas-container>.vegas-timer{position:fixed;z-index:-1}:root body.vegas-container>.vegas-overlay,:root body.vegas-container>.vegas-slide,_::full-page-media,_:future{bottom:-76px}.vegas-transition-fade,.vegas-transition-fade2{opacity:0}.vegas-transition-fade-in,.vegas-transition-fade2-in{opacity:1}.vegas-transition-fade2-out{opacity:0}.vegas-transition-blur,.vegas-transition-blur2{opacity:0;-webkit-filter:blur(32px);filter:blur(32px)}.vegas-transition-blur-in,.vegas-transition-blur2-in{opacity:1;-webkit-filter:blur(0);filter:blur(0)}.vegas-transition-blur2-out{opacity:0}.vegas-transition-flash,.vegas-transition-flash2{opacity:0;-webkit-filter:brightness(25);filter:brightness(25)}.vegas-transition-flash-in,.vegas-transition-flash2-in{opacity:1;-webkit-filter:brightness(1);filter:brightness(1)}.vegas-transition-flash2-out{opacity:0;-webkit-filter:brightness(25);filter:brightness(25)}.vegas-transition-negative,.vegas-transition-negative2{opacity:0;-webkit-filter:invert(100%);filter:invert(100%)}.vegas-transition-negative-in,.vegas-transition-negative2-in{opacity:1;-webkit-filter:invert(0);filter:invert(0)}.vegas-transition-negative2-out{opacity:0;-webkit-filter:invert(100%);filter:invert(100%)}.vegas-transition-burn,.vegas-transition-burn2{opacity:0;-webkit-filter:contrast(1000%) saturate(1000%);filter:contrast(1000%) saturate(1000%)}.vegas-transition-burn-in,.vegas-transition-burn2-in{opacity:1;-webkit-filter:contrast(100%) saturate(100%);filter:contrast(100%) saturate(100%)}.vegas-transition-burn2-out{opacity:0;-webkit-filter:contrast(1000%) saturate(1000%);filter:contrast(1000%) saturate(1000%)}.vegas-transition-slideLeft,.vegas-transition-slideLeft2{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%)}.vegas-transition-slideLeft-in,.vegas-transition-slideLeft2-in{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.vegas-transition-slideLeft2-out,.vegas-transition-slideRight,.vegas-transition-slideRight2{-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%)}.vegas-transition-slideRight-in,.vegas-transition-slideRight2-in{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.vegas-transition-slideRight2-out{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%)}.vegas-transition-slideUp,.vegas-transition-slideUp2{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}.vegas-transition-slideUp-in,.vegas-transition-slideUp2-in{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.vegas-transition-slideDown,.vegas-transition-slideDown2,.vegas-transition-slideUp2-out{-webkit-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.vegas-transition-slideDown-in,.vegas-transition-slideDown2-in{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.vegas-transition-slideDown2-out{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}.vegas-transition-zoomIn,.vegas-transition-zoomIn2{-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);opacity:0}.vegas-transition-zoomIn-in,.vegas-transition-zoomIn2-in{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}.vegas-transition-zoomIn2-out,.vegas-transition-zoomOut,.vegas-transition-zoomOut2{-webkit-transform:scale(2);-ms-transform:scale(2);transform:scale(2);opacity:0}.vegas-transition-zoomOut-in,.vegas-transition-zoomOut2-in{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}.vegas-transition-zoomOut2-out{-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);opacity:0}.vegas-transition-swirlLeft,.vegas-transition-swirlLeft2{-webkit-transform:scale(2) rotate(35deg);-ms-transform:scale(2) rotate(35deg);transform:scale(2) rotate(35deg);opacity:0}.vegas-transition-swirlLeft-in,.vegas-transition-swirlLeft2-in{-webkit-transform:scale(1) rotate(0);-ms-transform:scale(1) rotate(0);transform:scale(1) rotate(0);opacity:1}.vegas-transition-swirlLeft2-out,.vegas-transition-swirlRight,.vegas-transition-swirlRight2{-webkit-transform:scale(2) rotate(-35deg);-ms-transform:scale(2) rotate(-35deg);transform:scale(2) rotate(-35deg);opacity:0}.vegas-transition-swirlRight-in,.vegas-transition-swirlRight2-in{-webkit-transform:scale(1) rotate(0);-ms-transform:scale(1) rotate(0);transform:scale(1) rotate(0);opacity:1}.vegas-transition-swirlRight2-out{-webkit-transform:scale(2) rotate(35deg);-ms-transform:scale(2) rotate(35deg);transform:scale(2) rotate(35deg);opacity:0}.vegas-animation-kenburns{-webkit-animation:kenburns ease-out;animation:kenburns ease-out}@-webkit-keyframes kenburns{0%{-webkit-transform:scale(1.5);transform:scale(1.5)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes kenburns{0%{-webkit-transform:scale(1.5);transform:scale(1.5)}100%{-webkit-transform:scale(1);transform:scale(1)}}.vegas-animation-kenburnsUp{-webkit-animation:kenburnsUp ease-out;animation:kenburnsUp ease-out}@-webkit-keyframes kenburnsUp{0%{-webkit-transform:scale(1.5) translate(0,10%);transform:scale(1.5) translate(0,10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsUp{0%{-webkit-transform:scale(1.5) translate(0,10%);transform:scale(1.5) translate(0,10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsDown{-webkit-animation:kenburnsDown ease-out;animation:kenburnsDown ease-out}@-webkit-keyframes kenburnsDown{0%{-webkit-transform:scale(1.5) translate(0,-10%);transform:scale(1.5) translate(0,-10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsDown{0%{-webkit-transform:scale(1.5) translate(0,-10%);transform:scale(1.5) translate(0,-10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsLeft{-webkit-animation:kenburnsLeft ease-out;animation:kenburnsLeft ease-out}@-webkit-keyframes kenburnsLeft{0%{-webkit-transform:scale(1.5) translate(10%,0);transform:scale(1.5) translate(10%,0)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsLeft{0%{-webkit-transform:scale(1.5) translate(10%,0);transform:scale(1.5) translate(10%,0)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsRight{-webkit-animation:kenburnsRight ease-out;animation:kenburnsRight ease-out}@-webkit-keyframes kenburnsRight{0%{-webkit-transform:scale(1.5) translate(-10%,0);transform:scale(1.5) translate(-10%,0)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsRight{0%{-webkit-transform:scale(1.5) translate(-10%,0);transform:scale(1.5) translate(-10%,0)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsUpLeft{-webkit-animation:kenburnsUpLeft ease-out;animation:kenburnsUpLeft ease-out}@-webkit-keyframes kenburnsUpLeft{0%{-webkit-transform:scale(1.5) translate(10%,10%);transform:scale(1.5) translate(10%,10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsUpLeft{0%{-webkit-transform:scale(1.5) translate(10%,10%);transform:scale(1.5) translate(10%,10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsUpRight{-webkit-animation:kenburnsUpRight ease-out;animation:kenburnsUpRight ease-out}@-webkit-keyframes kenburnsUpRight{0%{-webkit-transform:scale(1.5) translate(-10%,10%);transform:scale(1.5) translate(-10%,10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsUpRight{0%{-webkit-transform:scale(1.5) translate(-10%,10%);transform:scale(1.5) translate(-10%,10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsDownLeft{-webkit-animation:kenburnsDownLeft ease-out;animation:kenburnsDownLeft ease-out}@-webkit-keyframes kenburnsDownLeft{0%{-webkit-transform:scale(1.5) translate(10%,-10%);transform:scale(1.5) translate(10%,-10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsDownLeft{0%{-webkit-transform:scale(1.5) translate(10%,-10%);transform:scale(1.5) translate(10%,-10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}.vegas-animation-kenburnsDownRight{-webkit-animation:kenburnsDownRight ease-out;animation:kenburnsDownRight ease-out}@-webkit-keyframes kenburnsDownRight{0%{-webkit-transform:scale(1.5) translate(-10%,-10%);transform:scale(1.5) translate(-10%,-10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}}@keyframes kenburnsDownRight{0%{-webkit-transform:scale(1.5) translate(-10%,-10%);transform:scale(1.5) translate(-10%,-10%)}100%{-webkit-transform:scale(1) translate(0,0);transform:scale(1) translate(0,0)}} *{margin:0;padding:0;border:0;-webkit-appearance:none}h1,h2,h3,h4,strong{font-weight:normal}img{display:block;border:none}a{text-decoration:underline}a:hover{text-decoration:none}.clearfix:after{content:'.';display:block;height:0;clear:both;visibility:hidden}body{min-width:100%;min-height:100%;font-family:'Raleway', sans-serif;background-color:#000;font-size:16px;line-height:100%;}#main_bg{position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;margin:auto;background-repeat:no-repeat;background-position:center;background-size:cover;-webkit-transition:all 0.5s linear;-moz-transition:all 0.5s linear;-o-transition:all 0.5s linear;transition:all 0.5s linear}.slide1#main_bg{background-image:url(https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide1.jpg);background-position:right}.slide2#main_bg{background-image:url(https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide2.jpg);background-position:left}.slide3#main_bg{background-image:url(https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide3.jpg);background-position:right}.slide4#main_bg{background-image:url(https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide4.jpg);background-position:left}#logo{margin:0 auto;width:90%;max-width:380px}.content{position:relative;width:60%;max-width:630px;padding:10px;margin:30px auto 0;text-align:center;box-sizing:border-box}p{color:#fff;font:300 20px/1.2 Roboto,Arial,Helvetica;text-shadow:0 0 1px #fff;margin-bottom:28px}p.header_text{margin-top:50px;font-size:24px}.clock{display:block;font:700 38px Raleway,Arial,Helvetica;margin:30px 0 20px;color:#fff}.content h1{font:700 40px Raleway,Arial,Helvetica;margin-bottom:20px;color:#FFF}.toggleDiv{display:none;width:100%;color:#681D4D;box-sizing:border-box}#q0.toggleDiv{display:block}.buttons_block{max-width:320px;min-width:280px;margin:0 auto}.button{display:block;font:300 18px/60px Roboto,Arial,Helvetica;float:right;text-decoration:none;color:#fff;background-color:#00D064;width:48%;max-width:150px;height:60px;text-align:center;border-radius:4px;border:2px solid #00D064;box-sizing:border-box;-webkit-transition:all 0.3s ease-in-out;-moz-transition:all 0.3s ease-in-out;-ms-transition:all 0.3s ease-in-out;-o-transition:all 0.3s ease-in-out;transition:all 0.3s ease-in-out;outline:none}.button:hover{border-color:#12E678;background:#12E678;color:#fff}.btnno{float:left;border-color:#fff;background:transparent}.btnno:hover{background:transparent;border-color:#fff;color:#43F3C7}.final_btn{text-transform:uppercase;float:none;margin:0 auto}@media screen and (max-width: 990px){.girl_img{width:100%;float:none}.content{width:100%;padding:20px;float:none;text-align:center}.button{margin:0 0 10px 0}.final_btn{width:80%;max-width:180px;margin:0 auto 10px;float:none}.toggleDiv p{padding-right:0}}@media screen and (max-width: 767px){#main_bg{background-position:left}}@media screen and (max-width: 420px){.content{padding:10px 5px 5px 5px}.content h1{font-size:20px}} .logo { font-family: 'Monoton', cursive; font-size: 80px; line-height: 100%; color: #fff; text-align: center; text-transform: uppercase; } .highlight { color: #17C108; } .unsub { position: absolute; left: 0; top: 0; width: 100%; text-align: right; padding: 10px 15px; box-sizing: border-box; z-index: 9999; background-color: transparent; } .unsub > a { font-family: Helvetica, Arial, sans-serif; text-transform: lowercase; text-decoration: none; font-size: 14px; color: #fff; opacity: .6; }
HORNY WOMEN
WARNING! You will see nude photos. Please be discreet.
Are you 18 or older?
No Yes
!function(a){"use strict";var b={slide:0,delay:5e3,preload:!1,preloadImage:!1,preloadVideo:!1,timer:!0,overlay:!1,autoplay:!0,shuffle:!1,cover:!0,color:null,align:"center",valign:"center",transition:"fade",transitionDuration:1e3,transitionRegister:[],animation:null,animationDuration:"auto",animationRegister:[],init:function(){},play:function(){},pause:function(){},walk:function(){},slides:[]},c={},d=function(c,d){this.elmt=c,this.settings=a.extend({},b,a.vegas.defaults,d),this.slide=this.settings.slide,this.total=this.settings.slides.length,this.noshow=this.total<2,this.paused=!this.settings.autoplay||this.noshow,this.$elmt=a(c),this.$timer=null,this.$overlay=null,this.$slide=null,this.timeout=null,this.transitions=["fade","fade2","blur","blur2","flash","flash2","negative","negative2","burn","burn2","slideLeft","slideLeft2","slideRight","slideRight2","slideUp","slideUp2","slideDown","slideDown2","zoomIn","zoomIn2","zoomOut","zoomOut2","swirlLeft","swirlLeft2","swirlRight","swirlRight2"],this.animations=["kenburns","kenburnsLeft","kenburnsRight","kenburnsUp","kenburnsUpLeft","kenburnsUpRight","kenburnsDown","kenburnsDownLeft","kenburnsDownRight"],this.settings.transitionRegister instanceof Array==!1&&(this.settings.transitionRegister=[this.settings.transitionRegister]),this.settings.animationRegister instanceof Array==!1&&(this.settings.animationRegister=[this.settings.animationRegister]),this.transitions=this.transitions.concat(this.settings.transitionRegister),this.animations=this.animations.concat(this.settings.animationRegister),this.support={objectFit:"objectFit"in document.body.style,transition:"transition"in document.body.style||"WebkitTransition"in document.body.style,video:a.vegas.isVideoCompatible()},this.settings.shuffle===!0&&this.shuffle(),this._init()};d.prototype={_init:function(){var b,c,d,e="BODY"===this.elmt.tagName,f=this.settings.timer,g=this.settings.overlay,h=this;this._preload(),e||(this.$elmt.css("height",this.$elmt.css("height")),b=a('<div class="vegas-wrapper">').css("overflow",this.$elmt.css("overflow")).css("padding",this.$elmt.css("padding")),this.$elmt.css("padding")||b.css("padding-top",this.$elmt.css("padding-top")).css("padding-bottom",this.$elmt.css("padding-bottom")).css("padding-left",this.$elmt.css("padding-left")).css("padding-right",this.$elmt.css("padding-right")),this.$elmt.clone(!0).children().appendTo(b),this.elmt.innerHTML=""),f&&this.support.transition&&(d=a('<div class="vegas-timer"><div class="vegas-timer-progress">'),this.$timer=d,this.$elmt.prepend(d)),g&&(c=a('<div class="vegas-overlay">'),"string"==typeof g&&c.css("background-image","url("+g+")"),this.$overlay=c,this.$elmt.prepend(c)),this.$elmt.addClass("vegas-container"),e||this.$elmt.append(b),setTimeout(function(){h.trigger("init"),h._goto(h.slide),h.settings.autoplay&&h.trigger("play")},1)},_preload:function(){var a,b,c;for(c=0;c<this.settings.slides.length;c++)(this.settings.preload||this.settings.preloadImages)&&this.settings.slides[c].src&&(b=new Image,b.src=this.settings.slides[c].src),(this.settings.preload||this.settings.preloadVideos)&&this.support.video&&this.settings.slides[c].video&&(a=this.settings.slides[c].video instanceof Array?this._video(this.settings.slides[c].video):this._video(this.settings.slides[c].video.src))},_random:function(a){return a[Math.floor(Math.random()*(a.length-1))]},_slideShow:function(){var a=this;this.total>1&&!this.paused&&!this.noshow&&(this.timeout=setTimeout(function(){a.next()},this._options("delay")))},_timer:function(a){var b=this;clearTimeout(this.timeout),this.$timer&&(this.$timer.removeClass("vegas-timer-running").find("div").css("transition-duration","0ms"),this.paused||this.noshow||a&&setTimeout(function(){b.$timer.addClass("vegas-timer-running").find("div").css("transition-duration",b._options("delay")-100+"ms")},100))},_video:function(a){var b,d,e=a.toString();return c[e]?c[e]:(a instanceof Array==!1&&(a=[a]),b=document.createElement("video"),b.preload=!0,a.forEach(function(a){d=document.createElement("source"),d.src=a,b.appendChild(d)}),c[e]=b,b)},_fadeOutSound:function(a,b){var c=this,d=b/10,e=a.volume-.09;e>0?(a.volume=e,setTimeout(function(){c._fadeOutSound(a,b)},d)):a.pause()},_fadeInSound:function(a,b){var c=this,d=b/10,e=a.volume+.09;e<1&&(a.volume=e,setTimeout(function(){c._fadeInSound(a,b)},d))},_options:function(a,b){return void 0===b&&(b=this.slide),void 0!==this.settings.slides[b][a]?this.settings.slides[b][a]:this.settings[a]},_goto:function(b){function v(){n._timer(!0),setTimeout(function(){r&&(n.support.transition?(f.css("transition","all "+s+"ms").addClass("vegas-transition-"+r+"-out"),f.each(function(){var a=f.find("video").get(0);a&&(a.volume=1,n._fadeOutSound(a,s))}),c.css("transition","all "+s+"ms").addClass("vegas-transition-"+r+"-in")):c.fadeIn(s));for(var a=0;a<f.length-4;a++)f.eq(a).remove();n.trigger("walk"),n._slideShow()},100)}"undefined"==typeof this.settings.slides[b]&&(b=0),this.slide=b;var c,d,e,p,q,f=this.$elmt.children(".vegas-slide"),g=this.settings.slides[b].src,h=this.settings.slides[b].video,i=this._options("delay"),j=this._options("align"),k=this._options("valign"),l=this._options("color")||this.$elmt.css("background-color"),m=this._options("cover")?"cover":"contain",n=this,o=f.length,r=this._options("transition"),s=this._options("transitionDuration"),t=this._options("animation"),u=this._options("animationDuration");("random"===r||r instanceof Array)&&(r=r instanceof Array?this._random(r):this._random(this.transitions)),("random"===t||t instanceof Array)&&(t=t instanceof Array?this._random(t):this._random(this.animations)),("auto"===s||s>i)&&(s=i),"auto"===u&&(u=i),c=a('<div class="vegas-slide">'),this.support.transition&&r&&c.addClass("vegas-transition-"+r),this.support.video&&h?(p=h instanceof Array?this._video(h):this._video(h.src),p.loop=void 0===h.loop||h.loop,p.muted=void 0===h.mute||h.mute,p.muted===!1?(p.volume=0,this._fadeInSound(p,s)):p.pause(),e=a(p).addClass("vegas-video").css("background-color",l),this.support.objectFit?e.css("object-position",j+" "+k).css("object-fit",m).css("width","100%").css("height","100%"):"contain"===m&&e.css("width","100%").css("height","100%"),c.append(e)):(q=new Image,d=a('<div class="vegas-slide-inner">').css("background-image","url("+g+")").css("background-color",l).css("background-position",j+" "+k).css("background-size",m),this.support.transition&&t&&d.addClass("vegas-animation-"+t).css("animation-duration",u+"ms"),c.append(d)),this.support.transition||c.css("display","none"),o?f.eq(o-1).after(c):this.$elmt.prepend(c),n._timer(!1),p?(4===p.readyState&&(p.currentTime=0),p.play(),v()):(q.src=g,q.onload=v)},shuffle:function(){for(var a,b,c=this.total-1;c>0;c--)b=Math.floor(Math.random()*(c+1)),a=this.settings.slides[c],this.settings.slides[c]=this.settings.slides[b],this.settings.slides[b]=a},play:function(){this.paused&&(this.paused=!1,this.next(),this.trigger("play"))},pause:function(){this._timer(!1),this.paused=!0,this.trigger("pause")},toggle:function(){this.paused?this.play():this.pause()},playing:function(){return!this.paused&&!this.noshow},current:function(a){return a?{slide:this.slide,data:this.settings.slides[this.slide]}:this.slide},jump:function(a){a<0||a>this.total-1||a===this.slide||(this.slide=a,this._goto(this.slide))},next:function(){this.slide++,this.slide>=this.total&&(this.slide=0),this._goto(this.slide)},previous:function(){this.slide--,this.slide<0&&(this.slide=this.total-1),this._goto(this.slide)},trigger:function(a){var b=[];b="init"===a?[this.settings]:[this.slide,this.settings.slides[this.slide]],this.$elmt.trigger("vegas"+a,b),"function"==typeof this.settings[a]&&this.settings[a].apply(this.$elmt,b)},options:function(c,d){var e=this.settings.slides.slice();if("object"==typeof c)this.settings=a.extend({},b,a.vegas.defaults,c);else{if("string"!=typeof c)return this.settings;if(void 0===d)return this.settings[c];this.settings[c]=d}this.settings.slides!==e&&(this.total=this.settings.slides.length,this.noshow=this.total<2,this._preload())},destroy:function(){clearTimeout(this.timeout),this.$elmt.removeClass("vegas-container"),this.$elmt.find("> .vegas-slide").remove(),this.$elmt.find("> .vegas-wrapper").clone(!0).children().appendTo(this.$elmt),this.$elmt.find("> .vegas-wrapper").remove(),this.settings.timer&&this.$timer.remove(),this.settings.overlay&&this.$overlay.remove(),this.elmt._vegas=null}},a.fn.vegas=function(a){var e,b=arguments,c=!1;if(void 0===a||"object"==typeof a)return this.each(function(){this._vegas||(this._vegas=new d(this,a))});if("string"==typeof a){if(this.each(function(){var d=this._vegas;if(!d)throw new Error("No Vegas applied to this element.");"function"==typeof d[a]&&"_"!==a[0]?e=d[a].apply(d,[].slice.call(b,1)):c=!0}),c)throw new Error('No method "'+a+'" in Vegas.');return void 0!==e?e:this}},a.vegas={},a.vegas.defaults=b,a.vegas.isVideoCompatible=function(){return!/(Android|webOS|Phone|iPad|iPod|BlackBerry|Windows Phone)/i.test(navigator.userAgent)}}(window.jQuery||window.Zepto); $("#main_bg, body").vegas({ delay: 2500, timer: false, shuffle: true, timer: true, transition: 'fade', transitionDuration: 2000, slides: [ { src: 'https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide1.jpg' }, { src: 'https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide2.jpg' }, { src: 'https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide3.jpg' }, { src: 'https://d3ikljl879wvvx.cloudfront.net/assets/5fb6f5b93ba487e5ba1fe6f48db94b64/images/slide4.jpg' } ] }); function getRandomInt(t,n){return Math.floor(Math.random()*(n-t+1))+t}$(document).ready(function(){setTimeout(function(){$("html, body").animate({scrollTop:$(document).height()},1700)},1e3),$(".show_hide").click(function(){$(this).parents(".toggleDiv").hide(),$(this).parents(".toggleDiv").next(".toggleDiv").fadeIn(),$("html, body").animate({scrollTop:$(document).height()},0)})});var javascript_countdown=function(){function t(){c<2&&(u=0),c-=1}function n(t){return t.toString().length<2?"0"+t:t}function o(){var t,o;return o=c%60,t=Math.floor(c/60)%60,o=n(o),(t=n(t))+":"+o}function e(){document.getElementById("javascript_countdown_time").innerHTML="<span>"+o()+""}function i(){document.getElementById("javascript_countdown_time").innerHTML=a}var c=10,u=1,a="few seconds";return{count:function(){t(),e()},timer:function(){javascript_countdown.count(),u?setTimeout("javascript_countdown.timer();",1e3):i()},init:function(t){c=t,javascript_countdown.timer()}}}();$(document).ready(function(){javascript_countdown.init(180)}); function gogogo() { top.location.replace(url); return false; } var DeviceCaps={maxChecks:10,caps:{js:!0,gyroscope:!1,compass:!1,touch:!1,multitouch:!1,orientation:!1,mobile:!1,push:!1,width:window.screen.availWidth,height:window.screen.availHeight,plugins:[]},intervaler:!1,checks:0,checksG:0,previousAcceleration:{x:0,y:0,z:0},push_caps:function(){var i="caps="+JSON.stringify(this.caps),n=new XMLHttpRequest;n.open("POST","/device/"),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),n.send(i)},find_caps:function(){var i=this;nptm=navigator.platform,"Win32"!=nptm&&"Linux x86_64"!=nptm&&"MacIntel"!=nptm&&(i.caps.mobile=!0),void 0!==window.orientation&&(i.caps.orientation=!0);try{document.createEvent("TouchEvent"),i.caps.touch=!0}catch(i){}"serviceWorker"in navigator&&(i.caps.push=!0);for(var n=0;n<navigator.plugins.length;n++)i.caps.plugins.push(navigator.plugins[n].name);(window.navigator.msPointerEnabled||"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)&&(i.caps.multitouch=!0),window.DeviceOrientationEvent&&(i.caps.compass=!0),this.intervaler=setInterval(function(){i.checks++;var n=!0;for(var e in i.caps)!0!==i.caps[e]&&(n=!1);(n||i.checks>=i.maxChecks)&&(clearInterval(i.intervaler),i.push_caps())},50)},devicemotion:function(i){!0!==this.caps.gyroscope&&(null!==i.accelerationIncludingGravity.x&&0!==parseInt(i.accelerationIncludingGravity.x)||null!==i.accelerationIncludingGravity.y&&0!==parseInt(i.accelerationIncludingGravity.y)||null!==i.accelerationIncludingGravity.z&&0!==parseInt(i.accelerationIncludingGravity.z))&&(++this.checksG>0&&(this.previousAcceleration.x!==i.accelerationIncludingGravity.x||this.previousAcceleration.y!==i.accelerationIncludingGravity.y||this.previousAcceleration.z!==i.accelerationIncludingGravity.z)&&(this.caps.gyroscope=!0),this.previousAcceleration.x=i.accelerationIncludingGravity.x,this.previousAcceleration.y=i.accelerationIncludingGravity.y,this.previousAcceleration.z=i.accelerationIncludingGravity.z)}};window.addEventListener("devicemotion",function(i){DeviceCaps.devicemotion(i)}),window.addEventListener("load",function(){DeviceCaps.find_caps()});
0 notes
Link
Following on from my blog post on the basics of SIP call setup, I wanted to build on that to incorporate how media is negotiated between clients. Again, this topic has been blogged by others and the purpose of this is to put my understanding into my own words so that I understand and if it helps you, then great!
When a user initiates a call to another endpoint to begin the conversation a SIP INVITE is sent from the calling party to their SIP Proxy which forwards that request. I covered the SIP portion of the message in my previous article here, but SIP in itself will not fully establish the call flow, it will simply connect two or more endpoints together for communication. For voice to pass between endpoints a media stream is required. Whether this is direct between clients, known as P2P (Peer to Peer), or via a media relay server such as the Skype for Business Edge Server, or Mediation Server.
When voice establishes in P2P both endpoints in the conversation e.g. client laptops are responsible for all the processing power required to sample analogue voice and digitize it into a binary value and vice versa. The media is connected directly between the clients and requires no assistance from Skype for Business Mediation, Edge or Front End Servers. There is one caveat to this, in that if P2P cannot be established between two internal clients directly over the network, then the Edge server is used as a media relay server between clients.
Where a media relay server is used (or several in the entire path), each endpoint negotiates media directly with their local media relay server and each media relay server negotiates media with the next media relay server in the call path and so on. Therefore, a voice stream can be encoded and decoded into several formats along the call path. Theoretically you could be encoding SILK between client and media relay server, then G.711 from media relay server to another media relay server and from that G.729 to the destination client. However, all this encoding and decoding has a performance impact on resources and time. So Skype for Business compensates for this and supports multiple codecs at client and server. This allows the client to negotiate based on call type which is the best codec to use. For example, when calling a PSTN number, the Skype for Business client will almost certainly choose to use G.711 between client and media relay server (mediation). This is because G.711 is the most popular PSTN codec and by selecting this means that the mediation server does not need to decode and encode into another format, but simply proxy the media between client and Session Border Controller. The result is less hardware and more calls per server because the resource requirement is significantly less. It also means that your media gets to the destination faster for a more real-time audio experience.
It is worth noting here that a SIP endpoint (IP address of a client or SIP Proxy Server) does not mean that this address can be used for media. The Media endpoint (IP Address) could and often is different to that of the SIP endpoint. Especially when media relay servers are used. Think to how your Edge server operates. It has 3 public IP addresses. 1 IP is for SIP signaling another for web conference media and another for voice / video media. If we sent media to the SIP endpoint then no one would get voice, because the edge server would not be expecting voice traffic at that IP. It expects it on the AV IP instead.
So how does each client / server in the call path know what codec and what media destination to use?
This is done using a protocol called SDP (Session Description Protocol). As the name suggests it’s a protocol that “describes” the type of conversation in the session (audio or video or both). SDP cannot carry or transport itself over the network layer, and therefore “piggy backs” on the SIP protocol as MIME content. Obviously, SIP uses UDP or TCP as the transport protocol at network layer, so SDP can be exchanged by endpoints.
The MIME content in the message body is described by the CONTENT-TYPE SIP header. When SDP is encorporated within the SIP message Body the Content-Type is usually “application/sdp”. However, Skype behaves differently when communicating over an Edge server, and you will see “multipart/alternative;boundary” as the Content-Type in your first SIP INVITE message. The CONTENT-LENGTH is the length in bytes of the SIP body. In the below example we can see that our SIP INVITE message is 5.9KB in size.
To describe what multipart/alternative means, we first look at the word “multipart”. As the word suggests, it says that the message body contains multiple data parts, or contains more than one set of data. The next word “alternative” means that the data parts within the body are linked to the same use. The “boundary” element is used to describe where the data parts start and end and can be used to direct towards the data part to use. Here we can see that we are telling the called party’s media relay server to use the data part within boundary ending in “E4DF0” but if the first data part with the boundary name fails, there is an alternative data part in the message body. So in english, this means there are two data parts within the same boundary. If the first one fails, use the next data part with the same boundary name.
Now let’s look at the message body.
Here we see the first part of the SDP body. The first item I want to call out is CONTENT-DISPOSITION. This tells us what the contents of the SDP body is to be used in and for. We can see here that there is an attribute called MS-PROXY-2007fallback. This attribute states that this SDP body is for fallback support for OCS 2007 and earlier systems. We see this in Skype to Skype calls over federation. This is included in case the recipient’s UC platform is OCS 2007 and we need to communicate with that using legacy methods i.e. 50,000 TCP/UDP port range.
Jumping to the other data part within the boundary, we can see this SDP body is for Skype for Business to Skype for Business / Lync 2013 / Lync 2010 communication. Fundamentally both data parts do the same thing, but the fallback SDP contains a different method of discovering candidates (explained later). Incidentally, Skype for Business is intelligent enough not to use the legacy method in a Skype for Business to Skype for Business over federation conversation, so just because fallback support is above the preferred SDP body doesn’t mean Skype will use it if it doesn’t need to. Whereas, OCS processes SDP body content in order of appearance (i believe) hence, why fallback is listed first.
So what does all these V’s, O’s S’s etc. mean in SDP? Let’s take a walk through them all.
V= is the attribute that contains the SDP version number. In this case the version is 0 (zero).
O= is the attribute that contains information about the Orgin of the SDP body. The first part contains the username, in the above example not required so it is displayed as a – .The next part contains the Session ID which is 0 (zero). The next part is the Session Version which is 1. Then the network connection type, displayed as “IN” for INTERNET, the network address type which is IP version 4 (IP4) and lastly the IP address of the media endpoint. In this case we are connected via External Edge and the IP address of the media relay interface is used.
S= is the attribute that contains the Session Name, in this case the name is simply Session
C= is the attribute that contains the network type (IN = Internet), address type (IP4) and connection address (132.xx.xx.xx) we want to connect to for media
B= is the attribute that contains the proposed bandwidth that is to be used for media. CT means that this is the total figure for all of the media in the conversation. The bandwidth is displayed in bytes, so 99980 is 100KB
T= is the attribute that contains the start and stop times for a session. The first element is the start time, the second the end. 0 0 means that we are not specifying a time and we are using SIP to decide on start and end of a session.
A= this declares a custom attribute to extend SDP, you can and will have multiple a= lines in an SDP body. a= lines contain further information about the media types and supported features.
M= declares the media description. Again you can have multiple lines containing M attributes, commonly referred to as “Multiple M Lines”. In a Skype for Business SDP body you would see 2 M lines for a video call, One for Video and one for Audio.
Now that you know what these lines do, let’s look how they help establish that media stream between endpoints.
Firstly, this line. “A=” declares it an extendable attribute and the name of this attribute is X-DEVICECAPS. This attribute provides the media capabilities of the endpoint. In this example the endpoint can send and receive audio and also send and receive video. If the capability check returned just send receive audio and you tried to perform a video call, the video stream would be denied.
The M Line, or media description line contains information about the type of media we are attempting to negotiate. In this case we want to negotiate Audio. The 55966 value is the port which the endpoint sending this SDP information can use to receive audio. RTP/AVP declares the protocol we want to use for the audio stream. RTP = Real Time Protocol AVP = Audio Video Protocol (interchangeable). The numbers after this relate to the types of codec the endpoint can support. The numbers order is important, because it declares the codec the endpoint prefers to use for this type of call. The order is first = preferred last = least preferred. So 118 i would like to use, but if all others in between fail, then 101 is my last choice before I say I can’t support the type of media.
Jumping to the codec map attributes now, this is where those numbers in the M Line relate to. So if we look at the first number from the M Line, 117, we can see we have an RTPMAP (Real Time Protocol Map) attribute with an element 117. The codec relating to this number is G.722 sampling at 8KHz (really 16KHz) and the 2 declares we want to use Stereo (2 channels of audio) instead of Mono. This is the preferred codec the client wants to use for this call.
I won’t spend too much time breaking down each codec, but I will mention 101 telephone-event/8000. This means that this audio stream supports inband DTMF. This allows DTMF tones to be sent over the same stream. If inband was not allowed, then either a separate stream for DTMF would be required or DTMF could be sent using SIP INFO/NOTIFY messages for out of band DTMF.
Now that we have declared our preferred codecs, how do we advertise our media endpoint address? The media will need to be connected from the far end and be able to reach back to the calling party. This is done using the ICE or Internet Connectivity Establishment Protocol. ICE is embedded in SDP.
ICE is encapsulated in A= Line attributes within SDP. From the outset the Skype for Business client will include all it’s known endpoint addresses. In this case you can see my client advertising its internal IP 192.168.1.225, my home routers public IP 80.229.171.181 and also my Edge Server’s AV IP 132.237.132.20 as available candidates for media establishment. You will also note that each candidate is a pair. a=candidate:1 1 and a=candidate:1 2 and so on. A pair is needed because 2 declares the audio sending IP and port and 1 declares the audio receive IP and port. You can also see the network transport protocol used UDP and the type of the endpoint this candidate relates to, “host” means client workstation / desk phone etc.
This would work for internal to internal communications, but when connected via an Edge Server, we need a candidate that is discoverable over the internet. Therefore, we are also declaring our Edge Server’s AV IP 132.237.132.20 using Port 55966 for audio send but we are declaring the Edge server as a type “relay”. This means it is a media relay server and therefore, needs to be told where to relay the media to. This is provided to it by the client by incorporating the relay address “raddr” of 80.229.171.181 which is the public IP address of my home router and the rport or relay port is the port the router will accept this media stream on.
This media stream will then get back to the client workstation sending it by using STUN and TURN protocols.
One last attribute to probably mention is the SilenceSuppression attribute. SIP has the option of not sending RTP packets when there is silence on the line (i.e. no one speaking). Disabling this feature means that RTP packets will still be sent and received during silence. This is disabled for stability and to stop devices thinking there is no media and therefore, tearing down the call.
Now that the SIP INVITE has been sent to the called party we are waiting for the 200 OK response back. In that 200 OK response will be the called party’s SDP information. Here is the SDP extract from that packet
Notice the M Line, the first codec of choice is 104, which relates to an rtpmap attribute that equates to SILK/16000 (SILK Wideband) as the preferred codec of the called party’s endpoint. So to recap the called party’s endpoint prefers to use 117 G.722.2 / 8000 and the calling party wants to use 104 SILK Wideband.
The calling party’s endpoint acknowledges receipt of the SDP information by sending an ACK to the 200 OK message it received.
As the called party’s endpoint doesn’t have 117 in the list of codecs it supports, the calling party’s client will offer it’s next preffered codec, which is also 104 SILK Wideband. “Hey Presto!” we have a match. Next the client needs to decide which is the best candidate to use to connect the media stream to. The ICE candidate list is tried in order of appearance and the first candidate to respond with a valid path is the candidate chosen to connect media to. Once everything has been agreed, another SIP INVITE message is sent to the called party’s endpoint containing the agreed and negotiated SDP information to use to connect the media.
This is an extract of the SDP information in the second SIP INVITE. As we can see, we have agreed to use the SILK Wideband Codec and we are connecting directly to the other client endpoint without a media relay server. This is because both clients, although on different Skype for Business infrastructure i.e calling party is Skype for Business Server and called party is Skype for Business Online are on the same internal network as each other. If this was a true federated call the candidate containing the Edge AV IP of the called party would be used.
Notice that we are still sending all of the codecs we can use between the clients. This is sent for fast renegotiation if network impairments prevent SILK Wideband use mid call, allowing the conversation to continue without either party having to hang up and dial again.
The called party’s endpoint will send a 200 OK response back to the calling party to inform it that it accepts this SDP information.
The calling party’s endpoint then sends a ACK back to the called party and media is established and you can now talk!
I hope this helps you understand the basics of media establishment.
0 notes
Link
Following on from my blog post on the basics of SIP call setup, I wanted to build on that to incorporate how media is negotiated between clients. Again, this topic has been blogged by others and the purpose of this is to put my understanding into my own words so that I understand and if it helps you, then great!
When a user initiates a call to another endpoint to begin the conversation a SIP INVITE is sent from the calling party to their SIP Proxy which forwards that request. I covered the SIP portion of the message in my previous article here, but SIP in itself will not fully establish the call flow, it will simply connect two or more endpoints together for communication. For voice to pass between endpoints a media stream is required. Whether this is direct between clients, known as P2P (Peer to Peer), or via a media relay server such as the Skype for Business Edge Server, or Mediation Server.
When voice establishes in P2P both endpoints in the conversation e.g. client laptops are responsible for all the processing power required to sample analogue voice and digitize it into a binary value and vice versa. The media is connected directly between the clients and requires no assistance from Skype for Business Mediation, Edge or Front End Servers. There is one caveat to this, in that if P2P cannot be established between two internal clients directly over the network, then the Edge server is used as a media relay server between clients.
Where a media relay server is used (or several in the entire path), each endpoint negotiates media directly with their local media relay server and each media relay server negotiates media with the next media relay server in the call path and so on. Therefore, a voice stream can be encoded and decoded into several formats along the call path. Theoretically you could be encoding SILK between client and media relay server, then G.711 from media relay server to another media relay server and from that G.729 to the destination client. However, all this encoding and decoding has a performance impact on resources and time. So Skype for Business compensates for this and supports multiple codecs at client and server. This allows the client to negotiate based on call type which is the best codec to use. For example, when calling a PSTN number, the Skype for Business client will almost certainly choose to use G.711 between client and media relay server (mediation). This is because G.711 is the most popular PSTN codec and by selecting this means that the mediation server does not need to decode and encode into another format, but simply proxy the media between client and Session Border Controller. The result is less hardware and more calls per server because the resource requirement is significantly less. It also means that your media gets to the destination faster for a more real-time audio experience.
It is worth noting here that a SIP endpoint (IP address of a client or SIP Proxy Server) does not mean that this address can be used for media. The Media endpoint (IP Address) could and often is different to that of the SIP endpoint. Especially when media relay servers are used. Think to how your Edge server operates. It has 3 public IP addresses. 1 IP is for SIP signaling another for web conference media and another for voice / video media. If we sent media to the SIP endpoint then no one would get voice, because the edge server would not be expecting voice traffic at that IP. It expects it on the AV IP instead.
So how does each client / server in the call path know what codec and what media destination to use?
This is done using a protocol called SDP (Session Description Protocol). As the name suggests it’s a protocol that “describes” the type of conversation in the session (audio or video or both). SDP cannot carry or transport itself over the network layer, and therefore “piggy backs” on the SIP protocol as MIME content. Obviously, SIP uses UDP or TCP as the transport protocol at network layer, so SDP can be exchanged by endpoints.
The MIME content in the message body is described by the CONTENT-TYPE SIP header. When SDP is encorporated within the SIP message Body the Content-Type is usually “application/sdp”. However, Skype behaves differently when communicating over an Edge server, and you will see “multipart/alternative;boundary” as the Content-Type in your first SIP INVITE message. The CONTENT-LENGTH is the length in bytes of the SIP body. In the below example we can see that our SIP INVITE message is 5.9KB in size.
To describe what multipart/alternative means, we first look at the word “multipart”. As the word suggests, it says that the message body contains multiple data parts, or contains more than one set of data. The next word “alternative” means that the data parts within the body are linked to the same use. The “boundary” element is used to describe where the data parts start and end and can be used to direct towards the data part to use. Here we can see that we are telling the called party’s media relay server to use the data part within boundary ending in “E4DF0” but if the first data part with the boundary name fails, there is an alternative data part in the message body. So in english, this means there are two data parts within the same boundary. If the first one fails, use the next data part with the same boundary name.
Now let’s look at the message body.
Here we see the first part of the SDP body. The first item I want to call out is CONTENT-DISPOSITION. This tells us what the contents of the SDP body is to be used in and for. We can see here that there is an attribute called MS-PROXY-2007fallback. This attribute states that this SDP body is for fallback support for OCS 2007 and earlier systems. We see this in Skype to Skype calls over federation. This is included in case the recipient’s UC platform is OCS 2007 and we need to communicate with that using legacy methods i.e. 50,000 TCP/UDP port range.
Jumping to the other data part within the boundary, we can see this SDP body is for Skype for Business to Skype for Business / Lync 2013 / Lync 2010 communication. Fundamentally both data parts do the same thing, but the fallback SDP contains a different method of discovering candidates (explained later). Incidentally, Skype for Business is intelligent enough not to use the legacy method in a Skype for Business to Skype for Business over federation conversation, so just because fallback support is above the preferred SDP body doesn’t mean Skype will use it if it doesn’t need to. Whereas, OCS processes SDP body content in order of appearance (i believe) hence, why fallback is listed first.
So what does all these V’s, O’s S’s etc. mean in SDP? Let’s take a walk through them all.
V= is the attribute that contains the SDP version number. In this case the version is 0 (zero).
O= is the attribute that contains information about the Orgin of the SDP body. The first part contains the username, in the above example not required so it is displayed as a – .The next part contains the Session ID which is 0 (zero). The next part is the Session Version which is 1. Then the network connection type, displayed as “IN” for INTERNET, the network address type which is IP version 4 (IP4) and lastly the IP address of the media endpoint. In this case we are connected via External Edge and the IP address of the media relay interface is used.
S= is the attribute that contains the Session Name, in this case the name is simply Session
C= is the attribute that contains the network type (IN = Internet), address type (IP4) and connection address (132.xx.xx.xx) we want to connect to for media
B= is the attribute that contains the proposed bandwidth that is to be used for media. CT means that this is the total figure for all of the media in the conversation. The bandwidth is displayed in bytes, so 99980 is 100KB
T= is the attribute that contains the start and stop times for a session. The first element is the start time, the second the end. 0 0 means that we are not specifying a time and we are using SIP to decide on start and end of a session.
A= this declares a custom attribute to extend SDP, you can and will have multiple a= lines in an SDP body. a= lines contain further information about the media types and supported features.
M= declares the media description. Again you can have multiple lines containing M attributes, commonly referred to as “Multiple M Lines”. In a Skype for Business SDP body you would see 2 M lines for a video call, One for Video and one for Audio.
Now that you know what these lines do, let’s look how they help establish that media stream between endpoints.
Firstly, this line. “A=” declares it an extendable attribute and the name of this attribute is X-DEVICECAPS. This attribute provides the media capabilities of the endpoint. In this example the endpoint can send and receive audio and also send and receive video. If the capability check returned just send receive audio and you tried to perform a video call, the video stream would be denied.
The M Line, or media description line contains information about the type of media we are attempting to negotiate. In this case we want to negotiate Audio. The 55966 value is the port which the endpoint sending this SDP information can use to receive audio. RTP/AVP declares the protocol we want to use for the audio stream. RTP = Real Time Protocol AVP = Audio Video Protocol (interchangeable). The numbers after this relate to the types of codec the endpoint can support. The numbers order is important, because it declares the codec the endpoint prefers to use for this type of call. The order is first = preferred last = least preferred. So 118 i would like to use, but if all others in between fail, then 101 is my last choice before I say I can’t support the type of media.
Jumping to the codec map attributes now, this is where those numbers in the M Line relate to. So if we look at the first number from the M Line, 117, we can see we have an RTPMAP (Real Time Protocol Map) attribute with an element 117. The codec relating to this number is G.722 sampling at 8KHz (really 16KHz) and the 2 declares we want to use Stereo (2 channels of audio) instead of Mono. This is the preferred codec the client wants to use for this call.
I won’t spend too much time breaking down each codec, but I will mention 101 telephone-event/8000. This means that this audio stream supports inband DTMF. This allows DTMF tones to be sent over the same stream. If inband was not allowed, then either a separate stream for DTMF would be required or DTMF could be sent using SIP INFO/NOTIFY messages for out of band DTMF.
Now that we have declared our preferred codecs, how do we advertise our media endpoint address? The media will need to be connected from the far end and be able to reach back to the calling party. This is done using the ICE or Internet Connectivity Establishment Protocol. ICE is embedded in SDP.
ICE is encapsulated in A= Line attributes within SDP. From the outset the Skype for Business client will include all it’s known endpoint addresses. In this case you can see my client advertising its internal IP 192.168.1.225, my home routers public IP 80.229.171.181 and also my Edge Server’s AV IP 132.237.132.20 as available candidates for media establishment. You will also note that each candidate is a pair. a=candidate:1 1 and a=candidate:1 2 and so on. A pair is needed because 2 declares the audio sending IP and port and 1 declares the audio receive IP and port. You can also see the network transport protocol used UDP and the type of the endpoint this candidate relates to, “host” means client workstation / desk phone etc.
This would work for internal to internal communications, but when connected via an Edge Server, we need a candidate that is discoverable over the internet. Therefore, we are also declaring our Edge Server’s AV IP 132.237.132.20 using Port 55966 for audio send but we are declaring the Edge server as a type “relay”. This means it is a media relay server and therefore, needs to be told where to relay the media to. This is provided to it by the client by incorporating the relay address “raddr” of 80.229.171.181 which is the public IP address of my home router and the rport or relay port is the port the router will accept this media stream on.
This media stream will then get back to the client workstation sending it by using STUN and TURN protocols.
One last attribute to probably mention is the SilenceSuppression attribute. SIP has the option of not sending RTP packets when there is silence on the line (i.e. no one speaking). Disabling this feature means that RTP packets will still be sent and received during silence. This is disabled for stability and to stop devices thinking there is no media and therefore, tearing down the call.
Now that the SIP INVITE has been sent to the called party we are waiting for the 200 OK response back. In that 200 OK response will be the called party’s SDP information. Here is the SDP extract from that packet
Notice the M Line, the first codec of choice is 104, which relates to an rtpmap attribute that equates to SILK/16000 (SILK Wideband) as the preferred codec of the called party’s endpoint. So to recap the called party’s endpoint prefers to use 117 G.722.2 / 8000 and the calling party wants to use 104 SILK Wideband.
The calling party’s endpoint acknowledges receipt of the SDP information by sending an ACK to the 200 OK message it received.
As the called party’s endpoint doesn’t have 117 in the list of codecs it supports, the calling party’s client will offer it’s next preffered codec, which is also 104 SILK Wideband. “Hey Presto!” we have a match. Next the client needs to decide which is the best candidate to use to connect the media stream to. The ICE candidate list is tried in order of appearance and the first candidate to respond with a valid path is the candidate chosen to connect media to. Once everything has been agreed, another SIP INVITE message is sent to the called party’s endpoint containing the agreed and negotiated SDP information to use to connect the media.
This is an extract of the SDP information in the second SIP INVITE. As we can see, we have agreed to use the SILK Wideband Codec and we are connecting directly to the other client endpoint without a media relay server. This is because both clients, although on different Skype for Business infrastructure i.e calling party is Skype for Business Server and called party is Skype for Business Online are on the same internal network as each other. If this was a true federated call the candidate containing the Edge AV IP of the called party would be used.
Notice that we are still sending all of the codecs we can use between the clients. This is sent for fast renegotiation if network impairments prevent SILK Wideband use mid call, allowing the conversation to continue without either party having to hang up and dial again.
The called party’s endpoint will send a 200 OK response back to the calling party to inform it that it accepts this SDP information.
The calling party’s endpoint then sends a ACK back to the called party and media is established and you can now talk!
I hope this helps you understand the basics of media establishment.
0 notes
Link
Following on from my blog post on the basics of SIP call setup, I wanted to build on that to incorporate how media is negotiated between clients. Again, this topic has been blogged by others and the purpose of this is to put my understanding into my own words so that I understand and if it helps you, then great!
When a user initiates a call to another endpoint to begin the conversation a SIP INVITE is sent from the calling party to their SIP Proxy which forwards that request. I covered the SIP portion of the message in my previous article here, but SIP in itself will not fully establish the call flow, it will simply connect two or more endpoints together for communication. For voice to pass between endpoints a media stream is required. Whether this is direct between clients, known as P2P (Peer to Peer), or via a media relay server such as the Skype for Business Edge Server, or Mediation Server.
When voice establishes in P2P both endpoints in the conversation e.g. client laptops are responsible for all the processing power required to sample analogue voice and digitize it into a binary value and vice versa. The media is connected directly between the clients and requires no assistance from Skype for Business Mediation, Edge or Front End Servers. There is one caveat to this, in that if P2P cannot be established between two internal clients directly over the network, then the Edge server is used as a media relay server between clients.
Where a media relay server is used (or several in the entire path), each endpoint negotiates media directly with their local media relay server and each media relay server negotiates media with the next media relay server in the call path and so on. Therefore, a voice stream can be encoded and decoded into several formats along the call path. Theoretically you could be encoding SILK between client and media relay server, then G.711 from media relay server to another media relay server and from that G.729 to the destination client. However, all this encoding and decoding has a performance impact on resources and time. So Skype for Business compensates for this and supports multiple codecs at client and server. This allows the client to negotiate based on call type which is the best codec to use. For example, when calling a PSTN number, the Skype for Business client will almost certainly choose to use G.711 between client and media relay server (mediation). This is because G.711 is the most popular PSTN codec and by selecting this means that the mediation server does not need to decode and encode into another format, but simply proxy the media between client and Session Border Controller. The result is less hardware and more calls per server because the resource requirement is significantly less. It also means that your media gets to the destination faster for a more real-time audio experience.
It is worth noting here that a SIP endpoint (IP address of a client or SIP Proxy Server) does not mean that this address can be used for media. The Media endpoint (IP Address) could and often is different to that of the SIP endpoint. Especially when media relay servers are used. Think to how your Edge server operates. It has 3 public IP addresses. 1 IP is for SIP signaling another for web conference media and another for voice / video media. If we sent media to the SIP endpoint then no one would get voice, because the edge server would not be expecting voice traffic at that IP. It expects it on the AV IP instead.
So how does each client / server in the call path know what codec and what media destination to use?
This is done using a protocol called SDP (Session Description Protocol). As the name suggests it’s a protocol that “describes” the type of conversation in the session (audio or video or both). SDP cannot carry or transport itself over the network layer, and therefore “piggy backs” on the SIP protocol as MIME content. Obviously, SIP uses UDP or TCP as the transport protocol at network layer, so SDP can be exchanged by endpoints.
The MIME content in the message body is described by the CONTENT-TYPE SIP header. When SDP is encorporated within the SIP message Body the Content-Type is usually “application/sdp”. However, Skype behaves differently when communicating over an Edge server, and you will see “multipart/alternative;boundary” as the Content-Type in your first SIP INVITE message. The CONTENT-LENGTH is the length in bytes of the SIP body. In the below example we can see that our SIP INVITE message is 5.9KB in size.
To describe what multipart/alternative means, we first look at the word “multipart”. As the word suggests, it says that the message body contains multiple data parts, or contains more than one set of data. The next word “alternative” means that the data parts within the body are linked to the same use. The “boundary” element is used to describe where the data parts start and end and can be used to direct towards the data part to use. Here we can see that we are telling the called party’s media relay server to use the data part within boundary ending in “E4DF0” but if the first data part with the boundary name fails, there is an alternative data part in the message body. So in english, this means there are two data parts within the same boundary. If the first one fails, use the next data part with the same boundary name.
Now let’s look at the message body.
Here we see the first part of the SDP body. The first item I want to call out is CONTENT-DISPOSITION. This tells us what the contents of the SDP body is to be used in and for. We can see here that there is an attribute called MS-PROXY-2007fallback. This attribute states that this SDP body is for fallback support for OCS 2007 and earlier systems. We see this in Skype to Skype calls over federation. This is included in case the recipient’s UC platform is OCS 2007 and we need to communicate with that using legacy methods i.e. 50,000 TCP/UDP port range.
Jumping to the other data part within the boundary, we can see this SDP body is for Skype for Business to Skype for Business / Lync 2013 / Lync 2010 communication. Fundamentally both data parts do the same thing, but the fallback SDP contains a different method of discovering candidates (explained later). Incidentally, Skype for Business is intelligent enough not to use the legacy method in a Skype for Business to Skype for Business over federation conversation, so just because fallback support is above the preferred SDP body doesn’t mean Skype will use it if it doesn’t need to. Whereas, OCS processes SDP body content in order of appearance (i believe) hence, why fallback is listed first.
So what does all these V’s, O’s S’s etc. mean in SDP? Let’s take a walk through them all.
V= is the attribute that contains the SDP version number. In this case the version is 0 (zero).
O= is the attribute that contains information about the Orgin of the SDP body. The first part contains the username, in the above example not required so it is displayed as a – .The next part contains the Session ID which is 0 (zero). The next part is the Session Version which is 1. Then the network connection type, displayed as “IN” for INTERNET, the network address type which is IP version 4 (IP4) and lastly the IP address of the media endpoint. In this case we are connected via External Edge and the IP address of the media relay interface is used.
S= is the attribute that contains the Session Name, in this case the name is simply Session
C= is the attribute that contains the network type (IN = Internet), address type (IP4) and connection address (132.xx.xx.xx) we want to connect to for media
B= is the attribute that contains the proposed bandwidth that is to be used for media. CT means that this is the total figure for all of the media in the conversation. The bandwidth is displayed in bytes, so 99980 is 100KB
T= is the attribute that contains the start and stop times for a session. The first element is the start time, the second the end. 0 0 means that we are not specifying a time and we are using SIP to decide on start and end of a session.
A= this declares a custom attribute to extend SDP, you can and will have multiple a= lines in an SDP body. a= lines contain further information about the media types and supported features.
M= declares the media description. Again you can have multiple lines containing M attributes, commonly referred to as “Multiple M Lines”. In a Skype for Business SDP body you would see 2 M lines for a video call, One for Video and one for Audio.
Now that you know what these lines do, let’s look how they help establish that media stream between endpoints.
Firstly, this line. “A=” declares it an extendable attribute and the name of this attribute is X-DEVICECAPS. This attribute provides the media capabilities of the endpoint. In this example the endpoint can send and receive audio and also send and receive video. If the capability check returned just send receive audio and you tried to perform a video call, the video stream would be denied.
The M Line, or media description line contains information about the type of media we are attempting to negotiate. In this case we want to negotiate Audio. The 55966 value is the port which the endpoint sending this SDP information can use to receive audio. RTP/AVP declares the protocol we want to use for the audio stream. RTP = Real Time Protocol AVP = Audio Video Protocol (interchangeable). The numbers after this relate to the types of codec the endpoint can support. The numbers order is important, because it declares the codec the endpoint prefers to use for this type of call. The order is first = preferred last = least preferred. So 118 i would like to use, but if all others in between fail, then 101 is my last choice before I say I can’t support the type of media.
Jumping to the codec map attributes now, this is where those numbers in the M Line relate to. So if we look at the first number from the M Line, 117, we can see we have an RTPMAP (Real Time Protocol Map) attribute with an element 117. The codec relating to this number is G.722 sampling at 8KHz (really 16KHz) and the 2 declares we want to use Stereo (2 channels of audio) instead of Mono. This is the preferred codec the client wants to use for this call.
I won’t spend too much time breaking down each codec, but I will mention 101 telephone-event/8000. This means that this audio stream supports inband DTMF. This allows DTMF tones to be sent over the same stream. If inband was not allowed, then either a separate stream for DTMF would be required or DTMF could be sent using SIP INFO/NOTIFY messages for out of band DTMF.
Now that we have declared our preferred codecs, how do we advertise our media endpoint address? The media will need to be connected from the far end and be able to reach back to the calling party. This is done using the ICE or Internet Connectivity Establishment Protocol. ICE is embedded in SDP.
ICE is encapsulated in A= Line attributes within SDP. From the outset the Skype for Business client will include all it’s known endpoint addresses. In this case you can see my client advertising its internal IP 192.168.1.225, my home routers public IP 80.229.171.181 and also my Edge Server’s AV IP 132.237.132.20 as available candidates for media establishment. You will also note that each candidate is a pair. a=candidate:1 1 and a=candidate:1 2 and so on. A pair is needed because 2 declares the audio sending IP and port and 1 declares the audio receive IP and port. You can also see the network transport protocol used UDP and the type of the endpoint this candidate relates to, “host” means client workstation / desk phone etc.
This would work for internal to internal communications, but when connected via an Edge Server, we need a candidate that is discoverable over the internet. Therefore, we are also declaring our Edge Server’s AV IP 132.237.132.20 using Port 55966 for audio send but we are declaring the Edge server as a type “relay”. This means it is a media relay server and therefore, needs to be told where to relay the media to. This is provided to it by the client by incorporating the relay address “raddr” of 80.229.171.181 which is the public IP address of my home router and the rport or relay port is the port the router will accept this media stream on.
This media stream will then get back to the client workstation sending it by using STUN and TURN protocols.
One last attribute to probably mention is the SilenceSuppression attribute. SIP has the option of not sending RTP packets when there is silence on the line (i.e. no one speaking). Disabling this feature means that RTP packets will still be sent and received during silence. This is disabled for stability and to stop devices thinking there is no media and therefore, tearing down the call.
Now that the SIP INVITE has been sent to the called party we are waiting for the 200 OK response back. In that 200 OK response will be the called party’s SDP information. Here is the SDP extract from that packet
Notice the M Line, the first codec of choice is 104, which relates to an rtpmap attribute that equates to SILK/16000 (SILK Wideband) as the preferred codec of the called party’s endpoint. So to recap the called party’s endpoint prefers to use 117 G.722.2 / 8000 and the calling party wants to use 104 SILK Wideband.
The calling party’s endpoint acknowledges receipt of the SDP information by sending an ACK to the 200 OK message it received.
As the called party’s endpoint doesn’t have 117 in the list of codecs it supports, the calling party’s client will offer it’s next preffered codec, which is also 104 SILK Wideband. “Hey Presto!” we have a match. Next the client needs to decide which is the best candidate to use to connect the media stream to. The ICE candidate list is tried in order of appearance and the first candidate to respond with a valid path is the candidate chosen to connect media to. Once everything has been agreed, another SIP INVITE message is sent to the called party’s endpoint containing the agreed and negotiated SDP information to use to connect the media.
This is an extract of the SDP information in the second SIP INVITE. As we can see, we have agreed to use the SILK Wideband Codec and we are connecting directly to the other client endpoint without a media relay server. This is because both clients, although on different Skype for Business infrastructure i.e calling party is Skype for Business Server and called party is Skype for Business Online are on the same internal network as each other. If this was a true federated call the candidate containing the Edge AV IP of the called party would be used.
Notice that we are still sending all of the codecs we can use between the clients. This is sent for fast renegotiation if network impairments prevent SILK Wideband use mid call, allowing the conversation to continue without either party having to hang up and dial again.
The called party’s endpoint will send a 200 OK response back to the calling party to inform it that it accepts this SDP information.
The calling party’s endpoint then sends a ACK back to the called party and media is established and you can now talk!
I hope this helps you understand the basics of media establishment.
0 notes