sidetone

Usage

Calling out and in

The outside world is a trunk to a provider, a route that says which numbers go to it, and an inbound number that says where the provider's calls land. Three requests, and the next call uses them.

$ api -d '{"name":"provider","type":"register","host":"sip.provider.example","username":"acct","password":"secret"}' localhost:8080/v1/trunks
$ api -d '{"name":"national","prefix":"0","strip":1,"prepend":"+44","trunk_ids":[1]}' localhost:8080/v1/routes
$ api -d '{"number":"+441234567890","username":"1001"}' localhost:8080/v1/dids

Trunks

A trunk is a provider, or a peer, and how we reach them. Two kinds:

  • register: we log in to the provider with a username and password, as a phone would. Most consumer and small-business providers work this way, and registering is what lets the server work behind a router without port forwards.
  • ip: the peer is trusted by address. List its networks in source_cidrs; calls from those addresses are the trunk's, and need no password.

GET /v1/trunks shows whether each is registered and reachable, and the last error if not; the dashboard shows the same as Outside lines. A trunk also carries max_calls, a cap on calls through it at once, default_caller_id, the number to present when the user has none, and srtp to require encrypted audio on that leg.

Two settings depend on what the provider wants. caller_id_format says where the caller's number travels: from, pai (P-Asserted-Identity) or rpid. from_user is for providers that want your account name in the From header rather than the caller's number. See what a provider refuses below.

Routes

A number that is an extension rings that extension. Otherwise the route with the lowest priority wins, then the longest prefix. strip removes that many leading digits and prepend adds what the provider wants in front, so that people dial the way they always have and the provider sees international format. trunk_ids are tried in order, moving on only when a trunk is down, never after the far end said busy or no such number.

That is the whole dial plan. There is no scripting language, no pattern syntax beyond a prefix, and nothing to reload: the next call reads the routes as they stand.

Inbound numbers

Calls from a trunk reach an inbound number (a DID) or nothing. Each points at a destination: a user, a ring group, a queue, a menu or a business-hours schedule. The leading + does not matter when matching. A call for a number you have not listed is refused with 404, and the log says what the number was sent as, so that you can add exactly that.

When a provider refuses an outgoing call

The provider's own words are in the log, at info level, with the trunk and the number: the provider would not place the call, in its own words … status=403 reason="Username in From Field required". The caller only ever hears "temporarily unavailable", so the log is where the answer is. Two that come up:

  • "Username in From Field required" (sipgate, and others that authenticate on the From user): set the trunk's from_user to the account name you register with, and caller_id_format to pai, so the number you present travels in P-Asserted-Identity instead.
  • "Forbidden" with nothing else: usually the number you present. default_caller_id on the trunk, or caller_id on the user, must be a number the provider has given you.

Emergency numbers

emergency_numbers (Settings → Calls; the default is 112, 911 and 999, check it for your country) are never refused by a user's dialling rules, the call limits or the longest-call setting. They go out by the route that covers them, and nowhere at all if no route does: nothing is sent down a line nobody chose for it. A call refused for that reason is logged at warning level, naming the number. Each call that does go is logged as EMERGENCY CALL and counted in the metrics.

What sidetone cannot do is tell the emergency service where the caller is. That depends on what your provider has on file for your number; ask them.

Test mode

A new server starts in test mode (test_mode, Settings → Calls), because a system being built must not be able to call an ambulance because somebody mistyped. While it is on, the emergency numbers are refused with 403 "Blocked In Test Mode" and every attempt is logged with the number and who dialled it; they are left out of what a phone may dial without the send key; the console carries a banner above every page; and the log says so at every start.

Switch it off when the telephones are in service. That is how you say they are real. Whether you may run a telephone system that cannot reach the emergency services is a matter of law where you are, so do not leave it on by accident, and do not switch it off by accident either.

Protect yourself from toll fraud

A stolen phone password is how small phone systems get robbed: somebody registers with it from the other side of the world and dials premium numbers all weekend. The defaults are conservative; tighten them to what you actually need.

  • Per user: deny_prefixes (for example ["00","09"]) and allow_prefixes. A forwarded call is the forwarding user's call and obeys their rules.
  • Server-wide (Settings → Calls): max_calls_per_user, max_calls_global, and max_call_duration, a cap on how long any call can last.
  • Per trunk: max_calls.
  • Password guessing gets a source address banned. GET /v1/bans lists them, DELETE /v1/bans/{ip} lets one back in early; the thresholds are the guard_* settings under Settings → Protection.

Emergency numbers skip every one of these limits, on purpose.