GSM/LTE LabKit AppNote: Controlling the LabKit with Javascript

From YateBTS
Revision as of 17:39, 8 March 2018 by Iulian.Comanescu (Talk | contribs) (Created page with "Javascript inside YateBTS Due to YateBTS, the Legba GSM/LTE LabKit allows control of GSM/GPRS services such as messages, spee...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Javascript inside YateBTS

Due to YateBTS, the Legba GSM/LTE LabKit allows control of GSM/GPRS services such as messages, speech calls, SMS, voice calls, USSD or data traffic by means of Javascript functions. Use of Javascript is very convenient in various laboratory scenarios where networks have to be simulated or radio measurements are necessary. In this Application Note, we are describing the use of Javascript inside YateBTS, and also offering you a series of code examples which are released under a GPL license, so that you can use them as the basis for your various customizations.

Scope and Audience

This note is intended for systems integrators who what to use YateBTS to:

  • simulate GSM/GPRS mobile networks in testing environments
  • connect YateBTS into simplified roaming gateways
  • use YateGSM to make measurements on the GSM radio interface (power, timing advance, etc.).

The level of detail in this note is intended to give technical managers and developers a clear idea of what is possible and some idea of the level of effort required for their own applications.


YateBTS is based on the Yate telephony application server, which is written in a mix of C++ and Javascript.

YateBTS GSM/GPRS functions up to Layer 2 (LAPDm and RLC) are implemented in C++, but most Layer 3 functions are implemented in Javascript, using an embedded Javascript virtual machine inside Yate.

The Javascript is available to end-users and can be modified or replaced to support custom applications and communicate with outside systems over sockets or using standard protocols already supported by Yate. The various components of Yate/YateBTS communicate among them according to the following flows:

handset <--GSM--> ybts+mbts GSM L1/L2 in C++ <--messages--> L3 in Javascript <--sockets--> custom protocols
handset <--GSM--> ybts+mbts GSM L1/L2 in C++ <--messages--> L3 in Javascript <--other Yate modules--> standard telecom protocols

What you can do with Javascript inside YateBTS

YateBTS supports the following services:

  • registration/authentication
  • speech calls
  • text messaging (SMS)
  • USSD (commercial releases only)
  • GPRS.

The Javascript approach described in this application note allows complete control over these services, down to Layer 3, including:

  • IMSI/IMEI information
  • TMSI information and control
  • radio channel information (power, timing).

Why use Javascript?

  1. The Yate Javascript APIs give complete access to the GSM protocol at Layer 3 and higher, for both information and control
  2. The effort required to write your integration directly in Javascript is probably less than the effort to write an outside gateway between you application and some socket-based protocol like SIP
    • by the way, if you really want SIP, there is already Javascript that implements a SIP interface for YateBTS that is given as an example in this application note.

Writing custom applications for YateBTS is a matter of writing Javascript functions that process uplink GSM messages and respond with downlink GSM messages. The following sections give you more technical background on how that works.

Yate Message Passing

Yate is designed as a message-passing system. The structure of Yate is a central engine and a collection of modules that provide different services, like SIP interfaces, telnet access, call routing, SS7 interfaces, etc. YateBTS is a subset of modules in Yate.

  • These modules communicate by passing messages.
  • These messages are sets of key-value pairs, as strings.
  • Each module can install handlers for different message types with specific priority ordering.

When a module sends out (or "dispatches") a message, the engine offers the installed handlers for that message type to the message, in a priority order. Priority numbers run 1...100, with 100 being the strongest priority and handled first.

Each module can:

  • Handle the message and then tell the engine to delete it so that no more handlers are called.
  • Handle the message, possibly modifying it, and then tell the engine to continue offering it to handlers in other modules, continuing in priority order.

Among the Yate modules, ybts, translates between GSM L3 messages and Yate internal messages. The Javascript virtual machine is also a module. Javascript functions can be defined to handle and dispatch Yate messages. The Javascript functions can handle messages converted from GSM L3 by ybts and also dispatch messages that will be handled by ybts and converted back to GSM L3.

The overall message flow is:

handsets <--GSM--> ybts <--messages--> Yate engine <--messages--> Javascript

For more complete information about messages, see this page in the Yate documentation.

Example 1: Sending a Yate Message to YateBTS

For example, here is a Javascript function to send an SMS text message from Javascript using a Yate message:

<source lang='JavaScript'> // Send text as SMS to the handset with the given IMSI. // text, IMSI and senderNumber are all strings function sendSms(text, IMSI, senderNumber) {

   // All of the fields of the SMS TPDU and RPDU can be controlled here,
   // but this example relies on default values for simplicity.
   // Create the Yate message object.
   var m = new Message("msg.execute");
   // Add the RPDU source and destination numbers (SMSC numbers)
   m.caller = "123456";
   m.called = "123456";
   // Add the TPDU source number (sender mobile number)
   m["sms.caller"] = senderNumber;
   // Add the message body.
   m.text = text;
   // Add the destination IMSI
   m.callto = "ybts/IMSI" + IMSI;
   // Send the message Yate message, which will be handled by YateBTS,
   // resulting in an SMS being sent to the handset with the given IMSI.

} </source>

The flow is:

Javascript >--message--> Yate engine >--message--> ybts >--GSM--> handset

Example 2: Handling a Message

The following example receives and logs all of the mobile-originated SMS text messages sent through YateBTS. It returns false to allow the message to continue to be processed by any other module that might handle it. Had it returned true, the processing for this message would end at this function.

<source lang='Javascript'> // This is a Javascript function to receive and print an SMS text message // sent by a handset through YateBTS. function onMoSMS(msg) {

   // msg is the Yate message, which contains the SMS sent by the handset.
   if (msg.callto != "smsc_yatebts")
       return false;
   // Extract some fields from the message and print them to the Yate log.
   // These are just a few of what is available, for a simple example.
   var smsInfo = "Source: " + msg.imsi + " ";
   smsInfo = smsInfo + "Dest: " + msg["sms.called"] + " ";
   smsInfo = smsInfo + "Text: " + msg.text;
   engine.debug(engine.DebugInfo,"MO-SMS: " + smsInfo);
   // Do not stop the engine from calling other handlers for this Yate msg.
   // Maybe there are others.
   return false;

} // Install function onMoSMS as the handler for the msg.execute message type, with priority 80. Message.install(onMoSMS,"msg.execute",80); </source>

The flow is:

handset >--GSM--> ybts >--message--> Yate engine >--message--> Javascript

Accessing PHY Information

Every GSM uplink Yate message from ybts includes a field called phy_info that reports:

  • timing advance and timing error, in GSM symbol periods
    • timing advance is the actual current timing advance
    • timing advance error is the timing deviation of the recevied signal from the current timing advance
  • uplink RSSI in dB relative to the saturation point of the radio
  • actual transmitted uplink power in dBm, as reported by the handset on SACCH
  • downlink RSSI at the phone in dBm, as reported by the handset on SACCH
  • the Unix system time when the corresponding L1 message frame arrived in the radio

This information is encoded as a string. Here is an example of such a string:

TA=3 TE=0.000 UpRSSI=-18 TxPwr=23 DnRSSIdBm=-48 time=1516381399.897

Note: This information is provided for GSM 2G control messages carried over the radio interface on SDCCH and TCH. It is not present for GPRS control messages.

Note: One unit of timing advance corresponds to about 550 meters of propagation delay, however, TA cannot be used as a direct measure of distance because of unknown timing advance bias in the handset.

GPRS Control

GPRS connections are initiated with the call.route message, just like telephone calls. When the handset requests a GPRS connection, ybts sends a call.route message having a caller value of sgsn and route_type value of gprs. Further steps in the connection establishment process are signaled with call.control messages.

It is possible to intervene in the GPRS connection management process by installing custom Javascript handlers for these messages, at a higher priority than the existing handlers.


SMSCB is a system for broadcasting text messages to handsets. Although the name includes "SMS", the actual service is completely independent of SMS and uses different signaling.

To enable SMSCB in YateBTS, set Control.SMSCB to true or yes in the configuration file before starting YateBTS.

The SMSCB feature cannot be enabled or disabled after YateBTS is started.

YateBTS keeps an internal table of active SMSCB messages, which are repeated periodically.

Sending a SMSCB message

To start sending an SMSCB message, send a Yate call.control message to ybts to add it to the table. The fields of the message include entities conform to the GSM 03.38 and 03.41 technical specifications:

  • targetid = 'ybts'
  • component = 'ybts'
  • operation = 'cbadd'
  • dcs = data coding scheme, see GSM 03.41 9.2.18 and GSM 03.38 5
  • data = hex string encoding the message content
  • gs = geographic scope, see GSM 03.41
  • code = message code, see GSM 03.41
  • id = message id, see GSM 03.41

The message update number (GSM 03.41 will be updated automatically whenever the message is replaced with another call.control message.

Stopping from sending SMSCB messages

To stop sending an SMSCB message, send a Yate call.control message to ybts to remove it from the table, identifying the message by the same id tag used when it was added. The fields of the message are:

  • targetid = 'ybts'
  • component = 'ybts'
  • operation = 'cbdel'
  • code = same message code used to add the mesage
  • id = same id used to add the message

These operations can also be performed from the rmanager telnet interface using the control ybts command, giving these same message fields on the command line. For example:

control ybts cbadd id=2 code=2 gs=1 dcs=1 data=F4F29C9E769F1B
control ybts cbdel id=2 code=2

GPL Javascript for YateBTS

This section indexes some published examples of custom YateBTS applications written in Javascript. These are provided publicly under a GPLv2 license. Any of them might be a good starting point for your own custom integration.

Sending an SMS from the Yate telnet interface

This script allows an operator to send a text message to a specific IMSI from the Yate ramanger (telnet) interface.

How it works:

  • Messages from rmanager have the type chan.control.
  • The onControl function is installed as the handler for chan.control messages.
  • The onControl function extracts parsed tokens from the rmanager command and inserts them into the fields of a msg.execute message.
  • The onControl function dispatches the msg.execute message, which is then handled by the ybts module to send the text message to the handset on the radio interface.

The overall operation is:

console --telnet--> rmanager module --message--> Javascript --message--> ybts --GSM--> handset delivery

Integrating Yate with a VoIP/SMS Gateway

These scripts give an an example of integrating YateBTS with an outside VoIP/SMS gateway service, in this case, Tropo. They perform the following functions:

  • bman_regist.js - Register and authenticate SIMs using a local subscriber database and automatically assign temporary local-only numbers.
  • bman_route.js - Route calls through the Tropo VoIP gateway, using a sort of "NAT for phone numbers" routing algorithm that allows many subscribers to share a small set of routable numbers.
  • sms_cache_txt.js - Route SMS through the Tropo SMS gateway and provide a simplistic SMSC-like store and forward service.

The message flow is:

handsets <--GSM--> ybts <--messages--> local SMSC and PBX functions in Javascript <--SIP--> Tropo gateway <--various--> PSTN/PLMN

Running a Local GSM PBX ("Network in a PC")

This is the standard "network in a PC" script that ships with YateBTS. It provides these functions:

  • local subscriber database for registration and authentication (readUEs, onRegister, onAuth, onUnregister)
  • local phone-to-phone PBX-type calling (onRoute)
  • local SMS delivery and store-and-forward (onSms, onIdleAction)
  • option to configure a SIP trunk to connect to the PSTN for outbound calls (routeOutside)
  • rmanager commands to allow monitoring and control via Telnet (onCommand, onHelp, onComplete)

The operations are:

handsets <--GSM--> ybts <--messages--> local SMSC and PBX functions in Javascript <--SIP--> PSTN
handsets <--GSM/GPRS--> ybts <--messages--> local GPRS session mgt <--TUN--> internet access

Roaming on YateUCN over SIP

YateUCN is an unified core solution intended for LTE and upgrade from GSM/GPRS to LTE. Our partners at SS7ware provide it together with scripts that define its functionality.

The "roaming" script shipped with YateBTS provides a SIP interface to YateUCN, for interconnection to a mobile operator network. It can also can connect to the YateUCN Mini-Core or Hosted Core, which are SS7ware products intended for testing and demonstration.

The services are:

  • Registration over SIP
    • Like normal SIP channel-response authentication, but with parameters based on GSM location updating procedure
      • Hash algorithm is COMP-128 or Milenage.
      • Nonce and result lengths match GSM RAND and SRES lengths.
  • MO- and MT- speech calls with SIP
    • Handset identity based on IMSI
    • GSM 6.01 full rate codec
  • MO- and MT- SMS
    • SIP MESSAGE method, following the same format as for IMS
  • USSD over SIP (commercial release only)
  • GPRS, using either local IP breakout or a GTP-U tunnel

The message flow is:

handsets <--GSM--> ybts <--messages--> Roaming.js <--SIP--> YateUCN or Mini-Core <--SS7/SIP--> HLR and/or mobile operators


handsets <--GSM--> ybts <--messages--> Roaming.js <--SIP--> Hosted Core.