pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/36711?usp=email )


Change subject: asterisk: Introduce AMI_Adapter_CT
......................................................................

asterisk: Introduce AMI_Adapter_CT

This allows to keep string handling totally internal to the AMI_Adapter
component, which also means now the CLIENT port acts asynchronously on
full AMI messages.
This allows for instance using activated altsteps to ignore events or
answer to them.

Change-Id: Ibf230d2302fecf443f34e1c4d4acfd4802f4cc79
---
M asterisk/AMI_Functions.ttcn
M asterisk/Asterisk_Tests.ttcn
2 files changed, 126 insertions(+), 48 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks 
refs/changes/11/36711/1

diff --git a/asterisk/AMI_Functions.ttcn b/asterisk/AMI_Functions.ttcn
index 72420e1..6e0b8d0 100644
--- a/asterisk/AMI_Functions.ttcn
+++ b/asterisk/AMI_Functions.ttcn
@@ -167,6 +167,58 @@
        tr_AMI_Field_ActionId(action_id)
 );

+
+/***********************
+ * Adapter:
+ ***********************/
+
+type port AMI_Msg_PT message {
+       inout AMI_Msg;
+} with { extension "internal" };
+
+type component AMI_Adapter_CT {
+       port TELNETasp_PT AMI;
+       port AMI_Msg_PT CLIENT;
+}
+
+function f_AMI_Adapter_main() runs on AMI_Adapter_CT {
+       var AMI_Msg msg;
+
+       var charstring rx, buf := "";
+       var integer fd;
+
+       map(self:AMI, system:AMI);
+
+       while (true) {
+
+               alt {
+               [] AMI.receive(pattern "\n") {
+                       buf := buf & "\n";
+                       msg := dec_AMI_Msg(buf);
+                       buf := "";
+                       CLIENT.send(msg);
+                       };
+               [] AMI.receive(charstring:?) -> value rx {
+                       buf := buf & rx;
+                       };
+               [] AMI.receive(integer:?) -> value fd {
+                       if (fd == -1) {
+                               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, 
fail,
+                                                       "AMI Telnet Connection 
Failure: " & int2str(fd));
+                       } else {
+                               /* telnet connection succeeded */
+                       }
+                       }
+               [] CLIENT.receive(AMI_Msg:?) -> value msg {
+                       /* TODO: in the future, queue Action if there's already 
one Action in transit, to fullfill AMI requirements. */
+                       var charstring tx_txt := enc_AMI_Msg(msg);
+                       AMI.send(tx_txt);
+                       }
+               }
+       }
+}
+
+
 /*
  * Functions:
  */
@@ -223,62 +275,66 @@
        return field.val;
 }

-private function f_ami_wait_for_prompt_str(TELNETasp_PT pt, charstring 
log_label := "(?)")
-return charstring {
-       var charstring rx, buf := "";
-       var integer fd;
+function f_ami_transceive_ret(AMI_Msg_PT pt, template (value) AMI_Msg tx_msg, 
float rx_timeout := 10.0) return AMI_Msg {
+       var AMI_Msg rx_msg;
        timer T;

-       T.start(mp_ami_prompt_timeout);
+       T.start(rx_timeout);
+       pt.send(tx_msg);
        alt {
-       [] pt.receive(pattern "\n") { buf := buf & "\n" };
-       [] pt.receive(charstring:?) -> value rx { buf := buf & rx; repeat };
-       [] pt.receive(integer:?) -> value fd {
-               if (fd == -1) {
-                       Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
-                                               "AMI Telnet Connection Failure: 
" & log_label);
-               } else {
-                       repeat; /* telnet connection succeeded */
-               }
-       }
+       [] pt.receive(AMI_Msg:?) -> value rx_msg;
        [] T.timeout {
                Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
-                                       "AMI Timeout for prompt: " & log_label);
-               };
+                                       log2str("AMI Response timeout: ", 
tx_msg));
+               }
        }
        T.stop;
-       return buf;
+       return rx_msg;
+
 }

-function f_ami_wait_for_prompt(TELNETasp_PT pt, charstring log_label := "(?)") 
return AMI_Msg {
-       var charstring buf := f_ami_wait_for_prompt_str(pt, log_label);
-       var AMI_Msg msg := dec_AMI_Msg(buf);
-       return msg;
-}
-
-/* send a AMI command and obtain response until prompt is received */
-private function f_ami_transceive_ret_str(TELNETasp_PT pt, charstring tx) 
return charstring {
-       pt.send(tx);
-       return f_ami_wait_for_prompt_str(pt, tx);
-}
-
-function f_ami_transceive_ret(TELNETasp_PT pt, template (value) AMI_Msg 
tx_msg) return AMI_Msg {
-       var charstring tx_txt := enc_AMI_Msg(valueof(tx_msg));
-       var charstring resp_txt := f_ami_transceive_ret_str(pt, tx_txt);
-       return dec_AMI_Msg(resp_txt);
-}
-
-function f_ami_transceive_match(TELNETasp_PT pt,
-                               template (value) AMI_Msg tx_msg,
-                               template (present) AMI_Msg exp_ret := ?) {
-       var AMI_Msg ret := f_ami_transceive_ret(pt, tx_msg);
-       if (not match(ret, exp_ret)) {
+private altstep as_ami_rx_fail(AMI_Msg_PT pt, template AMI_Msg exp_msg := *)
+{
+       var AMI_Msg msg;
+       [] pt.receive(AMI_Msg:?) -> value msg {
                Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
-                       log2str("Non-matching AMI response: ", ret, " vs exp: 
", exp_ret));
+                                       log2str("Received unexpected AMI 
message := ", msg, "\nvs exp := ", exp_msg));
        }
 }

-function f_ami_transceive_match_response_success(TELNETasp_PT pt,
+altstep as_ami_expect_msg(AMI_Msg_PT pt, template (present) AMI_Msg 
msg_expect, boolean fail_others := true)
+{
+       [] pt.receive(msg_expect);
+       [fail_others] as_ami_rx_fail(pt, msg_expect);
+}
+
+function f_ami_transceive_match(AMI_Msg_PT pt,
+                               template (value) AMI_Msg tx_msg,
+                               template (present) AMI_Msg exp_ret := ?,
+                               boolean fail_others := true,
+                               float rx_timeout := 10.0) return AMI_Msg {
+       var AMI_Msg rx_msg;
+       timer T;
+
+       T.start(rx_timeout);
+       pt.send(tx_msg);
+       alt {
+       [] pt.receive(exp_ret) -> value rx_msg;
+       [not fail_others] pt.receive(AMI_Msg:?) -> value rx_msg {
+               log("AMI: Ignoring Rx msg ", rx_msg);
+               repeat;
+       }
+       [fail_others] as_ami_rx_fail(pt, exp_ret);
+       [] T.timeout {
+               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                                       log2str("AMI Response timeout: ", 
tx_msg));
+               }
+       }
+       T.stop;
+       return rx_msg;
+}
+
+function f_ami_transceive_match_response_success(AMI_Msg_PT pt,
                                                 template (value) AMI_Msg 
tx_msg) {
        var template (present) AMI_Msg exp_resp;
        var template (omit) charstring action_id := 
f_ami_msg_get_value(valueof(tx_msg), AMI_FIELD_ACTION_ID);
@@ -290,11 +346,11 @@
        f_ami_transceive_match(pt, tx_msg, exp_resp);
 }

-function f_ami_action_login(TELNETasp_PT pt, charstring username, charstring 
secret) {
+function f_ami_action_login(AMI_Msg_PT pt, charstring username, charstring 
secret) {
        f_ami_transceive_match_response_success(pt, 
ts_AMI_Action_Login(username, secret));
 }

-function f_ami_action_PJSIPRegister(TELNETasp_PT pt, charstring register) {
+function f_ami_action_PJSIPRegister(AMI_Msg_PT pt, charstring register) {
        var charstring reg_action_id := f_gen_action_id();
        f_ami_transceive_match_response_success(pt, 
ts_AMI_Action_PJSIPRegister(register, reg_action_id));
 }
diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index c94f97f..d2fc0d5 100644
--- a/asterisk/Asterisk_Tests.ttcn
+++ b/asterisk/Asterisk_Tests.ttcn
@@ -49,7 +49,9 @@
        /* Manages the IMS server Asterisk connects to: */
        var SIP_Emulation_CT vc_IMS;

-       port TELNETasp_PT AMI;
+       /* Connection towards Asterisk AMI iface: */
+       var AMI_Adapter_CT vc_AMI;
+       port AMI_Msg_PT AMI_CLIENT;

        port Coord_PT COORD;
        port IMSCoord_PT IMS_COORD;
@@ -70,8 +72,13 @@

 /* Initialize connection towards Asterisk AMI */
 private function f_init_ami() runs on test_CT {
-       map(self:AMI, system:AMI);
-       f_ami_action_login(AMI, mp_ami_user, mp_ami_secret);
+       var charstring id := "Asterisk_Tests_AMI_EMU";
+       vc_AMI := AMI_Adapter_CT.create(id);
+       connect(self:AMI_CLIENT, vc_AMI:CLIENT);
+       vc_AMI.start(f_AMI_Adapter_main());
+
+
+       f_ami_action_login(AMI_CLIENT, mp_ami_user, mp_ami_secret);
 }

 /* Local SIP UAs */

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/36711?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: Ibf230d2302fecf443f34e1c4d4acfd4802f4cc79
Gerrit-Change-Number: 36711
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to