Difference between revisions of "Javascript NiPC"

From YateBTS
Jump to: navigation, search
(welcome.js)
 
(6 intermediate revisions by the same user not shown)
Line 7: Line 7:
 
See [http://docs.yate.ro/wiki/Javascript Yate's Javascript implementation] for more information and examples.
 
See [http://docs.yate.ro/wiki/Javascript Yate's Javascript implementation] for more information and examples.
  
==NIP Setup==
+
==NiPC Setup==
  
The NIP application is composed of two Javascript scripts located in the '''nip''' directory from YateBTS sources:  
+
The NiPC application is composed of two Javascript scripts located in the '''nipc''' directory from YateBTS sources:  
* nip.js - a global script that contains basic HLR/AuC,VLR/MSC,SMSC for its users
+
* nipc.js - a global script that contains basic HLR/AuC,VLR/MSC,SMSC for its users
 
* welcome.js - a small IVR that welcomes the user into the network when calling (david - 32843) and routes him to an echo test or to a conference room based on the user's input
 
* welcome.js - a small IVR that welcomes the user into the network when calling (david - 32843) and routes him to an echo test or to a conference room based on the user's input
  
Line 24: Line 24:
 
===ybts.conf===
 
===ybts.conf===
  
You can enable NIP by setting the '''mode=nip''' in  the [ybts] section. This is the default behaviour. If the 'mode' is not set, then the NIP mode is loaded by default:
+
You can enable NiPC by setting the '''mode=nipc''' in  the [ybts] section. This is the default behaviour. If the 'mode' is not set, then the NiPC mode is loaded by default:
  
 
  [ybts]
 
  [ybts]
  mode=nip
+
  mode=nipc
  
 
===extmodule.conf===
 
===extmodule.conf===
Line 38: Line 38:
 
===subscribers.conf===
 
===subscribers.conf===
  
Use the [[Network_in_a_PC#Web_UI_for_NIP_Management|YateBTS LMI Web GUI]] to set subscribers or configure regexp.  
+
Use the [[Network_in_a_PC#Web_UI_for_NiPC_Management|YateBTS LMI Web GUI]] to set subscribers or configure regexp.  
  
 
From YateBTS machine access http://127.0.0.1/nib or http://ip_yatebts/nib from another server.
 
From YateBTS machine access http://127.0.0.1/nib or http://ip_yatebts/nib from another server.
Line 53: Line 53:
  
 
  ; !!! NOTE !!!
 
  ; !!! NOTE !!!
  ; This file is used when YateBTS is in NIP (Network in a PC) mode
+
  ; This file is used when YateBTS is in NiPC (Network in a PC) mode
  ; File generated by the YateBTS NIP interface
+
  ; File generated by the YateBTS NiPC interface
 
   
 
   
 
  [general]
 
  [general]
Line 97: Line 97:
 
  short_number=111
 
  short_number=111
  
==NIP Commands==
+
==NiPC Commands==
  
You can interact with the '''nip.js''' script by using Yate's Telnet interface.  
+
You can interact with the '''nipc.js''' script by using Yate's Telnet interface.  
 
'''5038''' is Yate's default rmanager port (port on which it accepts Telnet connections).  
 
'''5038''' is Yate's default rmanager port (port on which it accepts Telnet connections).  
 
Staring with version 2 you will see this information in the LMI Web GUI as well, but until then you can only retrieve them directly from Yate.
 
Staring with version 2 you will see this information in the LMI Web GUI as well, but until then you can only retrieve them directly from Yate.
Line 110: Line 110:
 
===List registered users===
 
===List registered users===
  
  nip list registered
+
  nipc list registered
 
Example output:
 
Example output:
 
  IMSI            MSISDN  
 
  IMSI            MSISDN  
Line 121: Line 121:
 
===Reload subscribers.conf configurations===
 
===Reload subscribers.conf configurations===
  
  nip reload
+
  nipc reload
  
 
This will reload settings from subscribers.conf without losing existing registrations. (This was added in YateBTS 3)
 
This will reload settings from subscribers.conf without losing existing registrations. (This was added in YateBTS 3)
Line 127: Line 127:
 
===List rejected IMSIs===
 
===List rejected IMSIs===
  
  nip list rejected
+
  nipc list rejected
  
 
Output example:
 
Output example:
Line 137: Line 137:
 
===List pending SMSs===
 
===List pending SMSs===
  
  nip list sms
+
  nipc list sms
  
 
Output example:
 
Output example:
Line 151: Line 151:
 
It's not necessary to read it when you are just starting with YateBTS.
 
It's not necessary to read it when you are just starting with YateBTS.
  
===nip.js===
+
===nipc.js===
  
 
This scripts implements a basic HLR, MSC/VLR and SMSC for local users.  
 
This scripts implements a basic HLR, MSC/VLR and SMSC for local users.  
Line 169: Line 169:
 
To implement a small local '''SMSC''':
 
To implement a small local '''SMSC''':
  
  Message.install(onIdleAction,"idle.execute",110,"module","nip_cache");
+
  Message.install(onIdleAction,"idle.execute",110,"module","nipc_cache");
  Message.install(onSMS,"msg.execute",80,"callto","nip_smsc");
+
  Message.install(onSMS,"msg.execute",80,"callto","nipc_smsc");
 
  Engine.setInterval(onInterval,1000);
 
  Engine.setInterval(onInterval,1000);
  
Line 182: Line 182:
 
====The main points in detail====
 
====The main points in detail====
  
Although '''nip.js''' is too large to be listed on the wiki, when inspecting the code you will notice various facts:
+
Although '''nipc.js''' is too large to be listed on the wiki, when inspecting the code you will notice various facts:
  
 
* for registration
 
* for registration
Line 196: Line 196:
  
 
* for SMSs
 
* for SMSs
** to route SMS you must handle the '''call.route''' with '''route_type=msg'''. We simply return the '''nip_smsc'''- string representing our SMSC (implemented in this scrip as well)
+
** to route SMS you must handle the '''call.route''' with '''route_type=msg'''. We simply return the '''nipc_smsc'''- string representing our SMSC (implemented in this scrip as well)
** as you saw above, the script catches the '''msg.execute''' with priority 80 when '''callto=nip_smsc'''.  
+
** as you saw above, the script catches the '''msg.execute''' with priority 80 when '''callto=nipc_smsc'''.  
 
** SMSs are stored locally and, afterwards, we periodically try to deliver them until the maximum number of attempts is exceeded
 
** SMSs are stored locally and, afterwards, we periodically try to deliver them until the maximum number of attempts is exceeded
 
** the mobile originated SMSs come decoded from the lower layer. Assuming A sends a SMS to B:
 
** the mobile originated SMSs come decoded from the lower layer. Assuming A sends a SMS to B:
Line 213: Line 213:
 
===welcome.js===
 
===welcome.js===
  
welcome.js is a '''routing script''', this is different from the global nip.js presented above.  
+
welcome.js is a '''routing script''', this is different from the global nipc.js presented above.  
 
Click on the link to read more about [http://docs.yate.ro/wiki/Javascript_routing Javascript routing scripts].
 
Click on the link to read more about [http://docs.yate.ro/wiki/Javascript_routing Javascript routing scripts].
  

Latest revision as of 15:26, 21 August 2017

The Network in a PC (NiPC) application is a demo application written in Javascript that comes by default with YateBTS.

It was provided to ease the use of YateBTS as a small network and as an example on how to build applications based on YateBTS.

For a recap of the features implemented see Network in a PC page.

See Yate's Javascript implementation for more information and examples.

NiPC Setup

The NiPC application is composed of two Javascript scripts located in the nipc directory from YateBTS sources:

  • nipc.js - a global script that contains basic HLR/AuC,VLR/MSC,SMSC for its users
  • welcome.js - a small IVR that welcomes the user into the network when calling (david - 32843) and routes him to an echo test or to a conference room based on the user's input

Note: Keep in mind that welcome.js can also be used in Roaming mode.

javascript.conf

To set it up, edit javascript.conf.

[general]
routing=welcome.js

ybts.conf

You can enable NiPC by setting the mode=nipc in the [ybts] section. This is the default behaviour. If the 'mode' is not set, then the NiPC mode is loaded by default:

[ybts]
mode=nipc

extmodule.conf

When using 2G or 3G authentication set in extmodule.conf:

[scripts]
gsm_auth.sh=

subscribers.conf

Use the YateBTS LMI Web GUI to set subscribers or configure regexp.

From YateBTS machine access http://127.0.0.1/nib or http://ip_yatebts/nib from another server.

You can also edit subscribers.conf located together with Yate's configuration files in /etc/yate or /usr/local/etc/yate but this is not recommended.

Required configurations in subscribers.conf:

  • country_code
  • configuring regexp OR adding subscribers

You can't use regexp and subscribers as the same time. If you configured a subscriber (even if it's not active), regexp setting will be ignored.

This is an example of subscribers.conf with subscribers set individually:

; !!! NOTE !!!
; This file is used when YateBTS is in NiPC (Network in a PC) mode
; File generated by the YateBTS NiPC interface

[general]
; Your Country code (where YateBTS is installed)
; Ex: 1 for US, 44 for UK
country_code=40

; Subscribers are accepted by either matching the IMSI against this configured 
; regular expression or by setting subscribers individually
; Note! If a regular expression is used, 2G/3G authentication cannot be used.
; Ex: regexp=^001
;regexp=^001

; you have to put subscriber IMSI as a category and the subscriber parameters 
; as keys

[001990010001014]
; Oficial phone number. Should include configured country code
; Ex: msisdn=10744341111
msisdn=10744341111

; Whether this subscriber is allowed to use the service
; Allowed values: on, off
; Ex: active=off
active=on

; Card secrety. Set or generated when SIMs are written
; Ex:ki=00112233445566778899aabbccddeeff
ki=00112233445566778899aabbccddeeff

; Operator secret. 
; Allowed values: empty for 2G IMSIs, 00000000000000000000000000000000 for 3G IMSIs.
; Ex: op=00000000000000000000000000000000

; SIM type
; Allowed values: 2G, 3G
; Ex: imsi_type=3G
imsi_type=2G

; Short number subscribers can use to dial each other. Can be empty or not set
; Ex:short_number=111
short_number=111

NiPC Commands

You can interact with the nipc.js script by using Yate's Telnet interface. 5038 is Yate's default rmanager port (port on which it accepts Telnet connections). Staring with version 2 you will see this information in the LMI Web GUI as well, but until then you can only retrieve them directly from Yate.

From the console:

telnet 127.0.0.1 5038

You can:

List registered users

nipc list registered

Example output:

IMSI            MSISDN 
--------------- ---------------
00101000000000   +3014567
00101001100110   +9233298
00101000000003   +3453456
00101000000002   +9999272

Reload subscribers.conf configurations

nipc reload

This will reload settings from subscribers.conf without losing existing registrations. (This was added in YateBTS 3)

List rejected IMSIs

nipc list rejected

Output example:

IMSI            No attempts register 
--------------- ---------------
10101000000000    1

List pending SMSs

nipc list sms

Output example:

FROM_IMSI        FROM_MSISDN        TO_IMSI        TO_MSISDN
--------------- --------------- --------------- ---------------
00101000000000  +3014567        00101000000002  +9999272

Implementation

NOTE! This information is for developers. 

You might also find this useful if you wish to modify the provided scripts. It's not necessary to read it when you are just starting with YateBTS.

nipc.js

This scripts implements a basic HLR, MSC/VLR and SMSC for local users. It's a global script.

Handled messages

To register and unregister users you need to handle user.register and user.unregister messages:

Message.install(onUnregister,"user.unregister",80);
Message.install(onRegister,"user.register",80);

To route calls between the local users and outside YateBTS you must handle the call.route message:

Message.install(onRoute,"call.route",80);

To implement a small local SMSC:

Message.install(onIdleAction,"idle.execute",110,"module","nipc_cache");
Message.install(onSMS,"msg.execute",80,"callto","nipc_smsc");
Engine.setInterval(onInterval,1000);

To provide telnet commands:

Message.install(onCommand,"engine.command",120);

When one of the messages handled by the script is received, the function associated with the handler will be called. For example, when the message call.route is received, the onRoute function is called.

The main points in detail

Although nipc.js is too large to be listed on the wiki, when inspecting the code you will notice various facts:

  • for registration
    • the IMSI is set in username parameter for user.register/user.unregister messages
    • you must return false to deny the registration (the message should not be handled even if you set the error)
  • for routing
    • call.route is used for routing calls, SMSs, USSDs. To distinguish between them, see route_type parameter. If the parameter is empty or missing, then it's assumed you are routing a call
    • again, the IMSI is set in username parameter
    • depending on the lower level, the caller parameter can look like: 'IMSI.....'. In this case, you should rewrite it to the real number associated to the IMSI before you finish routing
    • to finish routing a call (with or without an error) you must return true from the routing function. To leave the message to be handled in another module, use return false
    • the returned value should look like: ybts/IMSI00101000000000 or ybts/+998838838 (msisdn preceded by +) or ybts/IMEI....
  • for SMSs
    • to route SMS you must handle the call.route with route_type=msg. We simply return the nipc_smsc- string representing our SMSC (implemented in this scrip as well)
    • as you saw above, the script catches the msg.execute with priority 80 when callto=nipc_smsc.
    • SMSs are stored locally and, afterwards, we periodically try to deliver them until the maximum number of attempts is exceeded
    • the mobile originated SMSs come decoded from the lower layer. Assuming A sends a SMS to B:
      • the sms.called holds the real called number (B)
      • the caller parameter will look like IMSI..... (Ex: IMSI00101000000000) or +..... (subscriber msisdn). If it's in the IMSI format it must be rewritten to msisdn before sending the Mobile terminated (MT) SMS
      • the called parameter holds the number of the SMSC (if set in the phone)
      • the text parameter holds the text of the SMS
    • when delivering an SMS, you must send the msg.execute message with following parameters:
      • caller - SMSC number
      • called - destination number (B in above example)
      • sms.caller - source number (A in above example)
      • text - the text of the message
      • callto - IMSI resource looking like ybts/IMSI....... (Ex: ybts/IMSI00101000000000)

welcome.js

welcome.js is a routing script, this is different from the global nipc.js presented above. Click on the link to read more about Javascript routing scripts.

When calling the number 32843(david), a welcomeIVR function is called. This will play a prompt and in case user presses:

  • 1 - startEchoTest will be called,
  • 2 - sendToConference,
  • 3 - make outbound call to David.
function welcomeIVR(msg)
{
   Engine.debug(Engine.DebugInfo,"Got call to welcome IVR.");

   Message.install(onChanDtmf, "chan.dtmf", 90, "id", msg.id);
   Channel.callTo("wave/play/"+getPathPrompt("welcome.au"));

   if (state == "")
	// No digit was pressed
	// Wait aprox 10 seconds to see if digit is pressed
	Channel.callTo("wave/record/-",{"maxlen":180000});

   Engine.debug(Engine.DebugInfo,"Returned to main function in state '"+state+"'");
   if (state == "echoTest")
	Channel.callJust("external/playrec/echo.sh");
}

state = "";
prompts_dir = "";

Engine.debugName("welcome");

if (message.called=="32843")
   welcomeIVR(message);

This is the function that handles the received DTMFs.

function onChanDtmf(msg)
{
   if(msg.text == 1) {
	state = "echoTest";
	Channel.callTo("wave/play/"+getPathPrompt("echo.au"));
   }

   else if (msg.text == 2) 
	Channel.callJust("conf/333",{"lonely":true});

   else if (msg.text == 3)
	Channel.callJust("iax/iax:32843@83.166.206.79/32843",{"caller":"yatebts"});
	//Channel.callJust("iax/iax:090@192.168.1.1/090",{"caller":"yatebts"});
}