(39 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | Since version BrandMeister Core 20211013-125527 has support of Asterisk's AudioSockets | + | Since version BrandMeister Core 20211013-125527 has support of Asterisk's AudioSocket. |
+ | |||
+ | AudioSocket implementation on the Core side makes and receives DMR calls. Outgoing calls are based on VAD activity, call parameters should be predefined. On the Asterisk side all seems like a single duplex outgoing call. You are able to create more complex logic such DMR to phone and back by scripting capabilities on the both sides. | ||
+ | |||
+ | To use AudioSockets you have to configure each channel profile in Core's config. UUID is an optional parameter. When undefined, Core will generate new one on the start (each AudioSocket channel correspond to Core's connection context). Core allows only one connection per channel. New connection to the same channel will replace existing one. | ||
+ | |||
+ | To secure the system, Core authorises each connection by IP and UUID. Address can be IP or domain name. Core updates it only on start. You are able to update it in runtime via D-BUS call ''invokeCommand()''. Also configuration of allowed DMR IDs and call type can be changed in runtime by call ''setSpecificValue()''. See information bellow. | ||
You can generate static UUIDs here - https://www.uuidgenerator.net | You can generate static UUIDs here - https://www.uuidgenerator.net | ||
− | '''We strongly recommend you to use it | + | '''We strongly recommend you to use it on top of phone conference bridges with automatic dialout to BrandMeister Core''' |
+ | |||
+ | If you want to make a kind of telephony patch application that should initiate phone call by DMR, you can create a Registry plugin which has to initiate a call on the Asterisk side my using ARI (https://wiki.asterisk.org/wiki/display/AST/Getting+Started+with+ARI) | ||
− | == Asterisk | + | == Asterisk simple dialplan example == |
<pre> | <pre> | ||
exten = 101,1,Verbose("Call to AudioSocket via Channel interface") | exten = 101,1,Verbose("Call to AudioSocket via Channel interface") | ||
same = n,Answer() | same = n,Answer() | ||
− | same = n,Dial(AudioSocket/server.example.com:9092/ | + | same = n,Dial(AudioSocket/server.example.com:9092/6c7a28ca-4d20-4db3-9a8a-497594de57a8) |
same = n,Hangup() | same = n,Hangup() | ||
</pre> | </pre> | ||
Line 38: | Line 46: | ||
// <path to TTY device>[;speed=230400] - in case of USB Dongle | // <path to TTY device>[;speed=230400] - in case of USB Dongle | ||
location = "localhost:2460"; | location = "localhost:2460"; | ||
− | // Address of Asterisk server | + | // Address of Asterisk server (used to authorise incoming connection) |
address = "localhost"; | address = "localhost"; | ||
// VAD parameters | // VAD parameters | ||
Line 51: | Line 59: | ||
== API commands == | == API commands == | ||
+ | |||
+ | Please look at [[D-BUS API]] | ||
=== invokeCommand(context, command) === | === invokeCommand(context, command) === | ||
Line 57: | Line 67: | ||
* ''set address <asterisk address, domain names accepted>'' | * ''set address <asterisk address, domain names accepted>'' | ||
− | === setSpecificValue(context, parameter, value) | + | === setSpecificValue(context, parameter, value) / getSpecificValue(context, parameter) === |
<pre> | <pre> | ||
+ | #define VALUE_SOCKET_OUTGOING_MODE 0 | ||
#define VALUE_SOCKET_OUTGOING_SOURCE_ID 1 | #define VALUE_SOCKET_OUTGOING_SOURCE_ID 1 | ||
#define VALUE_SOCKET_OUTGOING_TARGET_ID 2 | #define VALUE_SOCKET_OUTGOING_TARGET_ID 2 | ||
Line 75: | Line 86: | ||
#define SOCKET_HOOK_TARGET_ID 2 | #define SOCKET_HOOK_TARGET_ID 2 | ||
</pre> | </pre> | ||
+ | |||
+ | === Note about hook mode === | ||
+ | |||
+ | * SOCKET_HOOK_TARGET_ID - Core uses pre-defined outgoing caller ID for private call or group ID for group call to hook calls automatically | ||
+ | * SOCKET_HOOK_CALL_BACK - the same as SOCKET_HOOK_TARGET_ID, but also checks source call ID for private calls (usable in case of private call bridging, locks routing to the pair of source ID + destination ID) | ||
+ | * SOCKET_HOOK_NONE - don't hook automatically, calls can be routed by Lua or Registry | ||
+ | |||
+ | == HTTP API for Asterisk == | ||
+ | |||
+ | HTTP API is another way to change/read DMR call settings from Asterisk dialplan. API can be called with the same prerequisites as a AudioSocket. | ||
+ | |||
+ | === Call semantic === | ||
+ | <pre> | ||
+ | GET http(s)://<core's address>:<core's http(s) port>/socket/<audiosocket uuid>[?<url-encoded query parameters>] | ||
+ | </pre> | ||
+ | |||
+ | Query parameters: | ||
+ | * '''source''' - set source ID for outgoing call and hook | ||
+ | * '''destination''' - set destination ID for outgoing call and hook | ||
+ | * '''mode''' - set outgoing call mode | ||
+ | * '''hook''' - change hook mode (should be a number) | ||
+ | * '''alias''' - set talker alias for outgoing call | ||
+ | |||
+ | All query parameters are optional, BrandMeister will modify corresponding values only for existing parameters. The result of call is a JSON structure with current values of parameters. Check API section above for parameter meanings and values. | ||
+ | |||
+ | === Dialplan example === | ||
+ | |||
+ | <pre> | ||
+ | exten = 102,1,Answer() | ||
+ | same = n,Set(CURL_RESULT=${CURL(http://server.example.com:8080/socket/6c7a28ca-4d20-4db3-9a8a-497594de57a8?source=${CALLERID(num)}&alias=${URIENCODE(${CALLERID(name)})})}) | ||
+ | same = n,Dial(AudioSocket/server.example.com:9092/6c7a28ca-4d20-4db3-9a8a-497594de57a8) | ||
+ | same = n,Hangup() | ||
+ | |||
+ | exten = 103,1,Answer() | ||
+ | same = n,Set(CURL_RESULT=${CURL(http://server.example.com:8080/socket/6c7a28ca-4d20-4db3-9a8a-497594de57a8)}) | ||
+ | same = n,Set(source_id=${JSONELEMENT(CURL_RESULT,incoming/source)}) | ||
+ | same = n,Verbose(source_id) | ||
+ | </pre> | ||
+ | |||
+ | === Returned JSON === | ||
+ | |||
+ | <pre> | ||
+ | { | ||
+ | "incoming" : | ||
+ | { | ||
+ | "mode" : 0, | ||
+ | "source" : 456, | ||
+ | "destination" : 123 | ||
+ | }, | ||
+ | "outgoing" : | ||
+ | { | ||
+ | "mode" : 0, | ||
+ | "source" : 123, | ||
+ | "destination" : 456 | ||
+ | }, | ||
+ | "hook" : 0 | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | * '''incoming''' - parameters of current or last received DMR call | ||
+ | * '''outgoing''' - parameters in use for outgoing DMR call and hook |
Since version BrandMeister Core 20211013-125527 has support of Asterisk's AudioSocket.
AudioSocket implementation on the Core side makes and receives DMR calls. Outgoing calls are based on VAD activity, call parameters should be predefined. On the Asterisk side all seems like a single duplex outgoing call. You are able to create more complex logic such DMR to phone and back by scripting capabilities on the both sides.
To use AudioSockets you have to configure each channel profile in Core's config. UUID is an optional parameter. When undefined, Core will generate new one on the start (each AudioSocket channel correspond to Core's connection context). Core allows only one connection per channel. New connection to the same channel will replace existing one.
To secure the system, Core authorises each connection by IP and UUID. Address can be IP or domain name. Core updates it only on start. You are able to update it in runtime via D-BUS call invokeCommand(). Also configuration of allowed DMR IDs and call type can be changed in runtime by call setSpecificValue(). See information bellow.
You can generate static UUIDs here - https://www.uuidgenerator.net
We strongly recommend you to use it on top of phone conference bridges with automatic dialout to BrandMeister Core
If you want to make a kind of telephony patch application that should initiate phone call by DMR, you can create a Registry plugin which has to initiate a call on the Asterisk side my using ARI (https://wiki.asterisk.org/wiki/display/AST/Getting+Started+with+ARI)
exten = 101,1,Verbose("Call to AudioSocket via Channel interface") same = n,Answer() same = n,Dial(AudioSocket/server.example.com:9092/6c7a28ca-4d20-4db3-9a8a-497594de57a8) same = n,Hangup()
AudioSocket : { port = 9092; // TCP port channels = [ "Socket20" ]; }; Socket20 : { // AudioSocket ID number = 20; // AudioSocket UUID (optional) identifier = "6c7a28ca-4d20-4db3-9a8a-497594de57a8"; // Codec type: // AMBEServer - to use with AMBEserver or dvemu (please check https://github.com/dl5di/OpenDV/tree/master/DummyRepeater) // USB Dongle - to use with DVSI USB-3000/USB-3003/USB-3012, NW ThumbDV/ThumbDV-3 or DV3K Dongle type = "AMBEServer"; // Location of codec: // <domain name>[:<port>][,<interval>] - in case of AMBEServer (interval - address refresh interval in seconds, 10 minutes by default) // <path to TTY device>[;speed=230400] - in case of USB Dongle location = "localhost:2460"; // Address of Asterisk server (used to authorise incoming connection) address = "localhost"; // VAD parameters start = 47; // Level percentage to start release = 10; // Level percentage to continue // Outgoing session parameters (optional) mode = "Group"; source = 1; destination = 9504; };
Please look at D-BUS API
#define VALUE_SOCKET_OUTGOING_MODE 0 #define VALUE_SOCKET_OUTGOING_SOURCE_ID 1 #define VALUE_SOCKET_OUTGOING_TARGET_ID 2 #define VALUE_SOCKET_INCOMING_MODE 3 #define VALUE_SOCKET_INCOMING_SOURCE_ID 4 #define VALUE_SOCKET_INCOMING_TARGET_ID 5 #define VALUE_SOCKET_HOOK_MODE 6 #define VALUE_SOCKET_CONNECTION_STATE 7 #define SOCKET_MODE_PRIVATE 0 #define SOCKET_MODE_GROUP 1 #define SOCKET_HOOK_NONE 0 #define SOCKET_HOOK_CALL_BACK 1 #define SOCKET_HOOK_TARGET_ID 2
HTTP API is another way to change/read DMR call settings from Asterisk dialplan. API can be called with the same prerequisites as a AudioSocket.
GET http(s)://<core's address>:<core's http(s) port>/socket/<audiosocket uuid>[?<url-encoded query parameters>]
Query parameters:
All query parameters are optional, BrandMeister will modify corresponding values only for existing parameters. The result of call is a JSON structure with current values of parameters. Check API section above for parameter meanings and values.
exten = 102,1,Answer() same = n,Set(CURL_RESULT=${CURL(http://server.example.com:8080/socket/6c7a28ca-4d20-4db3-9a8a-497594de57a8?source=${CALLERID(num)}&alias=${URIENCODE(${CALLERID(name)})})}) same = n,Dial(AudioSocket/server.example.com:9092/6c7a28ca-4d20-4db3-9a8a-497594de57a8) same = n,Hangup() exten = 103,1,Answer() same = n,Set(CURL_RESULT=${CURL(http://server.example.com:8080/socket/6c7a28ca-4d20-4db3-9a8a-497594de57a8)}) same = n,Set(source_id=${JSONELEMENT(CURL_RESULT,incoming/source)}) same = n,Verbose(source_id)
{ "incoming" : { "mode" : 0, "source" : 456, "destination" : 123 }, "outgoing" : { "mode" : 0, "source" : 123, "destination" : 456 }, "hook" : 0 }
Since version BrandMeister Core 20211013-125527 has support of Asterisk's AudioSockets
You can generate static UUIDs here - https://www.uuidgenerator.net
We strongly recommend you to use it in phone conference bridge with autodial to BrandMeister Core
exten = 101,1,Verbose("Call to AudioSocket via Channel interface") same = n,Answer() same = n,Dial(AudioSocket/server.example.com:9092/40325ec2-5efd-4bd3-805f-53576e581d13) same = n,Hangup()
AudioSocket : { port = 9092; // TCP port channels = [ "Socket20" ]; }; Socket20 : { // AudioSocket ID number = 20; // AudioSocket UUID (optional) identifier = "6c7a28ca-4d20-4db3-9a8a-497594de57a8"; // Codec type: // AMBEServer - to use with AMBEserver or dvemu (please check https://github.com/dl5di/OpenDV/tree/master/DummyRepeater) // USB Dongle - to use with DVSI USB-3000/USB-3003/USB-3012, NW ThumbDV/ThumbDV-3 or DV3K Dongle type = "AMBEServer"; // Location of codec: // <domain name>[:<port>][,<interval>] - in case of AMBEServer (interval - address refresh interval in seconds, 10 minutes by default) // <path to TTY device>[;speed=230400] - in case of USB Dongle location = "localhost:2460"; // Address of Asterisk server address = "localhost"; // VAD parameters start = 47; // Level percentage to start release = 10; // Level percentage to continue // Outgoing session parameters (optional) mode = "Group"; source = 1; destination = 9504; };
#define VALUE_SOCKET_OUTGOING_SOURCE_ID 1 #define VALUE_SOCKET_OUTGOING_TARGET_ID 2 #define VALUE_SOCKET_INCOMING_MODE 3 #define VALUE_SOCKET_INCOMING_SOURCE_ID 4 #define VALUE_SOCKET_INCOMING_TARGET_ID 5 #define VALUE_SOCKET_HOOK_MODE 6 #define VALUE_SOCKET_CONNECTION_STATE 7 #define SOCKET_MODE_PRIVATE 0 #define SOCKET_MODE_GROUP 1 #define SOCKET_HOOK_NONE 0 #define SOCKET_HOOK_CALL_BACK 1 #define SOCKET_HOOK_TARGET_ID 2