Documentation |
Documentation -> Tutorials -> Diameter Client/ServerThis page has been visited 1133 times. How to build and process Diameter requests using OpenSIPS scriptingby Liviu Chircu Table of Content (hide) 1. Setting up the freeDiameter librariesThis tutorial has been written for a Xubuntu 22.04 LTS, which comes with freeDiameter library v1.2.1 packages. Other distros, such as Debian 10, are also known to offer standard package-based support for freeDiameter v1.2.1, so they are expected to be compatible just as well. sudo apt -y install libfreediameter-dev 2. Installing the "aaa_diameter" OpenSIPS moduleIf you are building from source: include_modules=aaa_diameter make install
sudo apt -y install opensips-diameter-module 3. Defining a Generic Diameter Request + AnswerWhile the freeDiameter library is very robust, this also means it will be very nitpicky with its "known" set of Diameter Applications and Commands. The set of currently known apps and commands (along with each command's precise AVP structure!) make up the library's dictionary, in freeDiameter terminology.
ATTRIBUTE Exponent 429 integer32 ATTRIBUTE Value-Digits 447 integer64 ATTRIBUTE Cost-Unit 424 grouped { Value-Digits | REQUIRED | 1 Exponent | OPTIONAL | 1 } ATTRIBUTE Currency-Code 425 unsigned32 ATTRIBUTE Unit-Value 445 grouped { Value-Digits | REQUIRED | 1 Exponent | OPTIONAL | 1 } ATTRIBUTE Cost-Information 423 grouped { Unit-Value | REQUIRED | 1 Currency-Code | REQUIRED | 1 Cost-Unit | OPTIONAL | 1 } APPLICATION 42 My Diameter Application REQUEST 92001 My-Custom-Request { Origin-Host | REQUIRED | 1 Origin-Realm | REQUIRED | 1 Destination-Realm | REQUIRED | 1 Transaction-Id | REQUIRED | 1 Sip-From-Tag | REQUIRED | 1 Sip-To-Tag | REQUIRED | 1 Acct-Session-Id | REQUIRED | 1 Sip-Call-Duration | REQUIRED | 1 Sip-Call-Setuptime | REQUIRED | 1 Sip-Call-Created | REQUIRED | 1 Sip-Call-MSDuration | REQUIRED | 1 call_cost | REQUIRED | 1 Cost-Information | OPTIONAL | 1 } ANSWER 92001 My-Custom-Answer { Origin-Host | REQUIRED | 1 Origin-Realm | REQUIRED | 1 Destination-Realm | REQUIRED | 1 Transaction-Id | REQUIRED | 1 Result-Code | REQUIRED | 1 } 4. opensips.cfg: Sending Generic Diameter RequestsOpenSIPS 3.2 and above releases offer the option of building generic Diameter requests with full control over the AVPs of the request, as well as full access to the content of the response. Below is a short tutorial on how to send a Diameter request.
log_stdout = yes ... loadmodule "aaa_diameter.so" modparam("aaa_diameter", "fd_log_level", 0) modparam("aaa_diameter", "realm", "diameter.test") modparam("aaa_diameter", "peer_identity", "server") ...
# Building an sending an My-Custom-Request (92001) for the # My Diameter Application (42) $var(payload) = "[ { \"Origin-Host\": \"client.diameter.test\" }, { \"Origin-Realm\": \"diameter.test\" }, { \"Destination-Realm\": \"diameter.test\" }, { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, { \"Sip-Call-Duration\": 6 }, { \"Sip-Call-Setuptime\": 1 }, { \"Sip-Call-Created\": 1652372541 }, { \"Sip-Call-MSDuration\": 5850 }, { \"out_gw\": \"GW-774\" }, { \"cost\": \"10.84\" }, { \"Cost-Information\": [ {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, {\"Currency-Code\": 35} ]} ]";
dm_send_request(42, 92001, $var(payload), $var(rpl_avps));
$json(rpl) := $var(rpl_avps); xlog("Reply AVPs: $json(rpl)\n"); $var(i) = 0; while ($json(rpl[$var(i)])) { xlog(" AVP: $json(rpl[$var(i)])\n"); } 5. opensips.cfg: Processing Generic Diameter RequestsStarting with OpenSIPS 3.5, there is the option of acting as a Diameter Server and process incoming Diameter requests, as well as to provide the appropriate AVPs for the Diameter answer, which may also be an error, of course. Here are the steps to achieve this:
log_stdout = yes ... loadmodule "aaa_diameter.so" modparam("aaa_diameter", "fd_log_level", 0) modparam("aaa_diameter", "realm", "diameter.test") modparam("aaa_diameter", "peer_identity", "server") loadmodule "event_route.so" ... event_route [E_DM_REQUEST] { xlog("Req: $param(sess_id) / $param(app_id) / $param(cmd_code)\n"); xlog("AVPs: $param(avps_json)\n"); }
... $var(ans_avps) = "[ { \"Vendor-Specific-Application-Id\": [{ \"Vendor-Id\": 0 }] }, { \"Result-Code\": 2001 }, { \"Auth-Session-State\": 0 }, { \"Origin-Host\": \"opensips.diameter.test\" }, { \"Origin-Realm\": \"diameter.test\" } ]"; if (!dm_send_answer($var(ans_avps))) xlog("ERROR - failed to send Diameter answer\n"); |