Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » Support for WebSocket in Eclipse Titan
Support for WebSocket in Eclipse Titan [message #1767903] Wed, 12 July 2017 05:56 Go to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Dear all,

WebSocket is a computer communications protocol providing full-duplex communication channels over a single TCP connection. The WebSocket protocol was standardized by the IETF as RFC 6455.

Support for websocket in Titan comes in the form of a protocol module, see
https://github.com/eclipse/titan.ProtocolModules.WebSocket
whose usage will be exemplified below.


According to the RFC:

The protocol has two parts: a handshake and the data transfer.

   The handshake from the client looks as follows:

        GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Origin: http://example.com
        Sec-WebSocket-Protocol: chat, superchat
        Sec-WebSocket-Version: 13

   The handshake from the server looks as follows:

        HTTP/1.1 101 Switching Protocols
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
        Sec-WebSocket-Protocol: chat
 



The handshake part can be replicated using curl in HTTP or HTTPS mode:




curl -v -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: echo.websocket.org" -H "Origin: https://www.websocket.org" -H "Sec-Websocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-Websocket-Version: 13"  http://echo.websocket.org
* Rebuilt URL to: http://echo.websocket.org/
*   Trying 174.129.224.73...
* TCP_NODELAY set
* Connected to echo.websocket.org (174.129.224.73) port 80 (#0)
> GET / HTTP/1.1
> Host: echo.websocket.org
> User-Agent: curl/7.54.0
> Accept: */*
> Connection: Upgrade
> Upgrade: websocket
> Origin: https://www.websocket.org
> Sec-Websocket-Key: dGhlIHNhbXBsZSBub25jZQ==
> Sec-Websocket-Version: 13
> 
< HTTP/1.1 101 Web Socket Protocol Handshake
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: content-type
< Access-Control-Allow-Headers: authorization
< Access-Control-Allow-Headers: x-websocket-extensions
< Access-Control-Allow-Headers: x-websocket-version
< Access-Control-Allow-Headers: x-websocket-protocol
< Access-Control-Allow-Origin: https://www.websocket.org
< Connection: Upgrade
< Date: Mon, 10 Jul 2017 08:27:18 GMT
< Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
< Server: Kaazing Gateway
< Upgrade: websocket
< 
^C




curl -v -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: echo.websocket.org" -H "Origin: https://www.websocket.org" -H "Sec-Websocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-Websocket-Version: 13"  https://echo.websocket.org
* Rebuilt URL to: https://echo.websocket.org/
*   Trying 174.129.224.73...
* TCP_NODELAY set
* Connected to echo.websocket.org (174.129.224.73) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / AES128-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: OU=Domain Control Validated; CN=*.websocket.org
*  start date: Oct 21 19:51:38 2016 GMT
*  expire date: Oct 28 22:06:24 2018 GMT
*  subjectAltName: host "echo.websocket.org" matched cert's "*.websocket.org"
*  issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: echo.websocket.org
> User-Agent: curl/7.54.0
> Accept: */*
> Connection: Upgrade
> Upgrade: websocket
> Origin: https://www.websocket.org
> Sec-Websocket-Key: dGhlIHNhbXBsZSBub25jZQ==
> Sec-Websocket-Version: 13
> 
< HTTP/1.1 101 Web Socket Protocol Handshake
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: content-type
< Access-Control-Allow-Headers: authorization
< Access-Control-Allow-Headers: x-websocket-extensions
< Access-Control-Allow-Headers: x-websocket-version
< Access-Control-Allow-Headers: x-websocket-protocol
< Access-Control-Allow-Origin: https://www.websocket.org
< Connection: Upgrade
< Date: Mon, 10 Jul 2017 08:26:53 GMT
< Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
< Server: Kaazing Gateway
< Upgrade: websocket
< 
^C



In the below code I have used two protocol modules: HTTP, for the handhsake part and Websocket for the data transfer.
After establishing the TCP or TLS connection, an upgrade request to Websocket is sent. After this has been granted, we send a Websocket text message to the echo server; this message is returned
in the reply. One interesting particularity of the code is re-registration of the message length calculation function as we move from one protocol being carried over TCP to another .
The server/url being used is https://www.websocket.org/echo.html which also permits test of websocket capabilities from a browser.



module WS   {

modulepar {

  charstring tsp_hostname:="www.websocket.org"  
  charstring tsp_url:="/echo" 
  boolean    tsp_use_ssl:=false 
}

import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from HTTP_Types all;
import from HTTP_MessageLen all;
import from WebSocket_Types all;

//------------------------------------------------------------------------------
function f_ContentLength (in charstring par_body)  return integer
//------------------------------------------------------------------------------
{
  return (lengthof (par_body))
}

//*************************************************************************
function f_HTTPMessage_len(  in octetstring stream,   inout ro_integer args) return integer
//*************************************************************************
{    
  return ef_HTTPMessage_len(stream) ;   
}

//*************************************************************************
function f_HTTPMessage_len_ws(  in octetstring stream,   inout ro_integer args) return integer
//*************************************************************************
{    
  return f_WebSocket_calc_length(stream) ;                
}

type component GeneralComp
{
  port IPL4asp_PT p;
  timer t;    
  var IPL4asp_Types.Result  c_res:= { errorCode := omit, connId  := omit, os_error_code:=omit, os_error_text:= omit };   
}

type component SystemComp
{
  port IPL4asp_PT p;
}

template  WebSocket_PDU t_websocket (in charstring payload) := {
  fin_bit :='1'B,
  rsv1_bit  :='0'B,
  rsv2_bit  :='0'B,
  rsv3_bit  :='0'B,
  opcode:= Text_frame,
  mask_bit := '1'B,
  payload_len:=lengthof(char2oct(payload)),
  masking_key :='00000000'O,
  payload_data := {data := char2oct(payload)}
}

template  WebSocket_PDU t_websocket_conn_close := {
  fin_bit :='1'B,
  rsv1_bit  :='0'B,
  rsv2_bit  :='0'B,
  rsv3_bit  :='0'B,
  opcode:= Connection_Close,
  mask_bit := '1'B,
  payload_len:=2,
  masking_key :='00000000'O,
  payload_data := {close_data := {
    status_code:=1000,
    data:=omit
  }}
}

template  ASP_Send t_data1(in integer p_id ) :={
  connId:=p_id,
  proto:=omit,
  msg:=ef_HTTP_Encode(valueof(t_message("")))
}

template  ASP_Send t_data2(in integer p_id, in octetstring pdu ) :={
  connId:=p_id,
  proto:=omit,
  msg:=pdu
}

template HTTP_Message t_message (in charstring payload) := {
  msg := {{request_line :={GET,tsp_url,1,1}},{
      host := "echo.websocket.org",
      connection := {{"Upgrade"}},
      upgrade := {{"websocket"}},
      origin := "http://www.websocket.org",
      sec_websocket_key := "dGhlIHNhbXBsZSBub25jZQ==",
      sec_websocket_version := "13"
    },omit}
}with { optional "implicit omit" } 

testcase TC_websocket() runs on GeneralComp system SystemComp {
  var ASP_RecvFrom v_ASP_RecvFrom	
  var HTTP_Message v_HTTP_Message	
  var WebSocket_PDU  v_WebSocket_PDU

  var octetstring v_ws_pdu:=''O;
  var IPL4asp_Types.Result  vl_result; 
  var integer v_cid, v_ret;
  map(self:p, system:p); 

  vl_result := c_res;

  if(tsp_use_ssl) {
    vl_result :=f_IPL4_connect(p, tsp_hostname, 443,"",0, -1, {ssl := {} }, {}  );
  }
  else {

    vl_result :=f_IPL4_connect( p, tsp_hostname, 80,"",0, -1, {tcp := {} }, {} );
  }

  log("connect result",vl_result);
  if (not(ispresent(vl_result.connId)))
  {
    log("Could not connect");
    stop;
  } 

  v_cid:=vl_result.connId; 

  //register message length function of HTTP with IPL4:
  //*************************************************************************
  var f_IPL4_getMsgLen getMsg_Func := refers(f_HTTPMessage_len);
  f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
  //*************************************************************************

  p.send(t_data1(v_cid));
  t.start(1.0) 
  alt 
  { 
    [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom	{ 
      v_HTTP_Message:= ef_HTTP_Decode(v_ASP_RecvFrom.msg);
      log(v_HTTP_Message);
    }
    [] t.timeout{log("Bye")}

  } 

  //*************************************************************************
  //From here on, we move to websocket
  //*************************************************************************
  //register message length function of websocket with IPL4:
  //*************************************************************************
  getMsg_Func := refers(f_HTTPMessage_len_ws);
  f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
  //*************************************************************************

  log(valueof(t_websocket("Hail your Titan overlords!")))
  f_WebSocket_Encode(valueof(t_websocket("Hail your Titan overlords!")), v_ws_pdu)

//  log(v_ws_pdu)
//  f_WebSocket_Decode(v_ws_pdu, v_WebSocket_PDU)  //check
//  log(v_WebSocket_PDU)

  p.send(t_data2(v_cid, v_ws_pdu));
  t.start(1.0) 

  alt 
  { 
    [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom	{ 
      v_ret:= f_WebSocket_Decode(v_ASP_RecvFrom.msg,v_WebSocket_PDU ) 
      log("Decode return result : ",v_ret)
      log("Websocket response received : ",v_WebSocket_PDU)
    }
    [] t.timeout{log("Bye")}
  } 

//send conn_close
f_WebSocket_Encode(valueof(t_websocket_conn_close), v_ws_pdu);
 p.send(t_data2(v_cid, v_ws_pdu));
  t.start(1.0) 
  alt 
  { 
    [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom	{ 
      v_ret:= f_WebSocket_Decode(v_ASP_RecvFrom.msg,v_WebSocket_PDU ) 
      log("Decode return result : ",v_ret)
      log("Websocket response received : ",v_WebSocket_PDU)
    }
    [] t.timeout{log("Bye")}
  } 

//close  TCP/TLS connection

  vl_result :=    f_IPL4_close(p, v_cid)
  log("close result",vl_result) 
  setverdict(pass);
}

control{
  execute(TC_websocket());
}

}//endmodule  


The execution can be started as usual with:

ttcn3_start ./websocket WS.cfg


with the module parameters

WS.tsp_hostname:="www.websocket.org" 
WS.tsp_url:="/echo"
WS.tsp_use_ssl:=false


the following log is produced:

01:40:20.838994 - TTCN-3 Main Test Component started on ntaf. Version: CRL 113 200/6 R2A.
01:40:20.839117 - TTCN Logger v2.2 options: TimeStampFormat:=Time; LogEntityName:=No; LogEventTypes:=No; SourceInfoFormat:=Single; *.FileMask:=LOG_ALL; *.ConsoleMask:=ERROR | USER; LogFileSize:=0; LogFileNumber:=1; DiskFullAction:=Error
01:40:20.839457 - Connected to MC.
01:40:20.840346 - Executing control part of module WS.
01:40:20.840410 WS.ttcn:248 Execution of control part in module WS started.
01:40:20.840477 WS.ttcn:138 Test case TC_websocket started.
01:40:20.840510 WS.ttcn:138 Initializing variables, timers and ports of component type WS.GeneralComp inside testcase TC_websocket.
01:40:20.840578 WS.ttcn:138 Port p was started.
01:40:20.840602 WS.ttcn:138 Component type WS.GeneralComp was initialized.
01:40:20.840632 WS.ttcn:148 Mapping port mtc:p to system:p.
01:40:20.840728 WS.ttcn:148 Port p was mapped to system:p.
01:40:20.840796 WS.ttcn:148 Map operation of mtc:p to system:p finished.
01:40:20.840826 WS.ttcn:157 entering f__IPL4__PROVIDER__connect: :0 -> www.websocket.org:80 / TCP
01:40:21.030189 WS.ttcn:160 connect result{ errorCode := omit, connId := 1, os_error_code := omit, os_error_text := omit }
01:40:21.031292 WS.ttcn:176 Sent on p to system @IPL4asp_Types.ASP_Send : { connId := 1, proto := omit, msg := '474554202F6563686F20485454502F312E310D0A436F6E6E656374696F6E3A20557067726164650D0A486F73743A206563686F2E776562736F636B65742E6F72670D0A4F726967696E3A20687474703A2F2F7777772E776562736F636B65742E6F72670D0A5365632D576562736F636B65742D4B65793A206447686C49484E68625842735A5342756232356A5A513D3D0D0A5365632D576562736F636B65742D56657273696F6E3A2031330D0A557067726164653A20776562736F636B65740D0A0D0A'O ("GET /echo HTTP/1.1\r\nConnection: Upgrade\r\nHost: echo.websocket.org\r\nOrigin: http://www.websocket.org\r\nSec-Websocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-Websocket-Version: 13\r\nUpgrade: websocket\r\n\r\n") }
01:40:21.031575 WS.ttcn:177 Start timer t: 1 s
01:40:21.152570 WS.ttcn:179 Message enqueued on p from system @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "www.websocket.org", remPort := 80, locName := "192.168.139.129", locPort := 36766, proto := { tcp := { } }, userData := 0, msg := '485454502F312E31203130312057656220536F636B65742050726F746F636F6C2048616E647368616B650D0A4163636573732D436F6E74726F6C2D416C6C6F772D43726564656E7469616C733A20747275650D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20636F6E74656E742D747970650D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20617574686F72697A6174696F6E0D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20782D776562736F636B65742D657874656E73696F6E730D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20782D776562736F636B65742D76657273696F6E0D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20782D776562736F636B65742D70726F746F636F6C0D0A4163636573732D436F6E74726F6C2D416C6C6F772D4F726967696E3A20687474703A2F2F7777772E776562736F636B65742E6F72670D0A436F6E6E656374696F6E3A20557067726164650D0A446174653A204D6F6E2C203130204A756C20323031372030383A34303A353420474D540D0A5365632D576562536F636B65742D4163636570743A20733370504C4D426954786151396B59477A7A685A52624B2B784F6F3D0D0A5365727665723A204B61617A696E6720476174657761790D0A557067726164653A20776562736F636B65740D0A0D0A'O ("HTTP/1.1 101 Web Socket Protocol Handshake\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Headers: content-type\r\nAccess-Control-Allow-Headers: authorization\r\nAccess-Control-Allow-Headers: x-websocket-extensions\r\nAccess-Control-Allow-Headers: x-websocket-version\r\nAccess-Control-Allow-Headers: x-websocket-protocol\r\nAccess-Control-Allow-Origin: http://www.websocket.org\r\nConnection: Upgrade\r\nDate: Mon, 10 Jul 2017 08:40:54 GMT\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: Kaazing Gateway\r\nUpgrade: websocket\r\n\r\n") } id 1
01:40:21.152841 WS.ttcn:181 Receive operation on port p succeeded, message from system(): @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "www.websocket.org", remPort := 80, locName := "192.168.139.129", locPort := 36766, proto := { tcp := { } }, userData := 0, msg := '485454502F312E31203130312057656220536F636B65742050726F746F636F6C2048616E647368616B650D0A4163636573732D436F6E74726F6C2D416C6C6F772D43726564656E7469616C733A20747275650D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20636F6E74656E742D747970650D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20617574686F72697A6174696F6E0D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20782D776562736F636B65742D657874656E73696F6E730D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20782D776562736F636B65742D76657273696F6E0D0A4163636573732D436F6E74726F6C2D416C6C6F772D486561646572733A20782D776562736F636B65742D70726F746F636F6C0D0A4163636573732D436F6E74726F6C2D416C6C6F772D4F726967696E3A20687474703A2F2F7777772E776562736F636B65742E6F72670D0A436F6E6E656374696F6E3A20557067726164650D0A446174653A204D6F6E2C203130204A756C20323031372030383A34303A353420474D540D0A5365632D576562536F636B65742D4163636570743A20733370504C4D426954786151396B59477A7A685A52624B2B784F6F3D0D0A5365727665723A204B61617A696E6720476174657761790D0A557067726164653A20776562736F636B65740D0A0D0A'O ("HTTP/1.1 101 Web Socket Protocol Handshake\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Headers: content-type\r\nAccess-Control-Allow-Headers: authorization\r\nAccess-Control-Allow-Headers: x-websocket-extensions\r\nAccess-Control-Allow-Headers: x-websocket-version\r\nAccess-Control-Allow-Headers: x-websocket-protocol\r\nAccess-Control-Allow-Origin: http://www.websocket.org\r\nConnection: Upgrade\r\nDate: Mon, 10 Jul 2017 08:40:54 GMT\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: Kaazing Gateway\r\nUpgrade: websocket\r\n\r\n") } id 1
01:40:21.152927 WS.ttcn:181 Message with id 1 was extracted from the queue of p.
01:40:21.157111 WS.ttcn:183 { msg := { start_line := { status_line := { version_major := 1, version_minor := 1, status_code := 101, reason_phrase := "Web Socket Protocol Handshake" } }, headers := { accept := omit, accept_charset := omit, accept_encoding := omit, accept_language := omit, accept_ranges := omit, age := omit, allow := omit, authorization := omit, cache_control := omit, connection := { { "Upgrade" } }, content_disposition := omit, content_encoding := omit, content_language := omit, content_length := omit, content_location := omit, content_range := omit, content_type := omit, cookie := omit, dasl := omit, dav := omit, date := "Mon, 10 Jul 2017 08:40:54 GMT", depth := omit, destination := omit, etag := omit, expect := omit, expires := omit, forwarded := omit, fRom := omit, host := omit, http2_settings := omit, iF := omit, if_match := omit, if_modified_since := omit, if_none_match := omit, if_range := omit, if_schedule_tag_match := omit, if_unmodified_since := omit, last_modified := omit, location := omit, lock_token := omit, max_forwards := omit, mime_version := omit, ordering_type := omit, origin := omit, overwrite := omit, position := omit, pragma := omit, prefer := omit, preference_applied := omit, proxy_authenticate := omit, proxy_authorization := omit, range := omit, referer := omit, retry_after := omit, schedule_reply := omit, schedule_tag := omit, sec_websocket_accept := "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", sec_websocket_extensions := omit, sec_websocket_key := omit, sec_websocket_protocol := omit, sec_websocket_version := omit, server := "Kaazing Gateway", set_cookie := omit, slug := omit, strict_transport_security := omit, tE := omit, tImeout := omit, trailer := omit, transfer_encoding := omit, upgrade := { { "websocket" } }, user_agent := omit, vary := omit, via := omit, www_authenticate := omit, warning := omit, undefined_header_list := { { headerName := "Access-Control-Allow-Credentials", headerValue := "true" }, { headerName := "Access-Control-Allow-Headers", headerValue := "content-type" }, { headerName := "Access-Control-Allow-Headers", headerValue := "authorization" }, { headerName := "Access-Control-Allow-Headers", headerValue := "x-websocket-extensions" }, { headerName := "Access-Control-Allow-Headers", headerValue := "x-websocket-version" }, { headerName := "Access-Control-Allow-Headers", headerValue := "x-websocket-protocol" }, { headerName := "Access-Control-Allow-Origin", headerValue := "http://www.websocket.org" } } }, body := omit } }
01:40:21.158110 WS.ttcn:202 { fin_bit := '1'B, rsv1_bit := '0'B, rsv2_bit := '0'B, rsv3_bit := '0'B, opcode := Text_frame (1), mask_bit := '1'B, payload_len := 26, masking_key := '00000000'O, payload_data := { data := '4861696C20796F757220546974616E206F7665726C6F72647321'O ("Hail your Titan overlords!") } }
01:40:21.158597 WS.ttcn:209 Sent on p to system @IPL4asp_Types.ASP_Send : { connId := 1, proto := omit, msg := '819AADAB0F82E5CA66EE8DD260F7DF8B5BEBD9CA61A2C2DD6AF0C1C47DE6DE8A'O }
01:40:21.158863 WS.ttcn:210 Warning: Re-starting timer t, which is already active (running or expired).
01:40:21.158905 WS.ttcn:210 Start timer t: 1 s
01:40:21.272087 WS.ttcn:212 Message enqueued on p from system @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "www.websocket.org", remPort := 80, locName := "192.168.139.129", locPort := 36766, proto := { tcp := { } }, userData := 0, msg := '811A4861696C20796F757220546974616E206F7665726C6F72647321'O } id 2
01:40:21.272268 WS.ttcn:214 Receive operation on port p succeeded, message from system(): @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "www.websocket.org", remPort := 80, locName := "192.168.139.129", locPort := 36766, proto := { tcp := { } }, userData := 0, msg := '811A4861696C20796F757220546974616E206F7665726C6F72647321'O } id 2
01:40:21.272327 WS.ttcn:214 Message with id 2 was extracted from the queue of p.
01:40:21.272377 WS.ttcn:216 Decode return result : 0
01:40:21.272510 WS.ttcn:217 Websocket response received : { fin_bit := '1'B, rsv1_bit := '0'B, rsv2_bit := '0'B, rsv3_bit := '0'B, opcode := Text_frame (1), mask_bit := '0'B, payload_len := 26, masking_key := omit, payload_data := { data := '4861696C20796F757220546974616E206F7665726C6F72647321'O ("Hail your Titan overlords!") } }
01:40:21.272937 WS.ttcn:226 Sent on p to system @IPL4asp_Types.ASP_Send : { connId := 1, proto := omit, msg := '88827E5AF4997DB2'O }
01:40:21.273211 WS.ttcn:227 Warning: Re-starting timer t, which is already active (running or expired).
01:40:21.273274 WS.ttcn:227 Start timer t: 1 s
01:40:21.403266 WS.ttcn:229 Message enqueued on p from system @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "www.websocket.org", remPort := 80, locName := "192.168.139.129", locPort := 36766, proto := { tcp := { } }, userData := 0, msg := '880203E8'O } id 3
01:40:21.403379 WS.ttcn:231 Receive operation on port p succeeded, message from system(): @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "www.websocket.org", remPort := 80, locName := "192.168.139.129", locPort := 36766, proto := { tcp := { } }, userData := 0, msg := '880203E8'O } id 3
01:40:21.403412 WS.ttcn:231 Message with id 3 was extracted from the queue of p.
01:40:21.403441 WS.ttcn:233 Decode return result : 0
01:40:21.403520 WS.ttcn:234 Websocket response received : { fin_bit := '1'B, rsv1_bit := '0'B, rsv2_bit := '0'B, rsv3_bit := '0'B, opcode := Connection_Close (8), mask_bit := '0'B, payload_len := 2, masking_key := omit, payload_data := { close_data := { status_code := 1000, data := omit } } }
01:40:21.403610 WS.ttcn:242 p: f__IPL4__close:  proto { unspecified := { } } connId 1
01:40:21.403824 WS.ttcn:243 close result{ errorCode := omit, connId := 1, os_error_code := omit, os_error_text := omit }
01:40:21.403931 WS.ttcn:245 setverdict(pass): none -> pass
01:40:21.404012 WS.ttcn:245 Terminating component type WS.GeneralComp.
01:40:21.404048 WS.ttcn:245 Stop timer t: 1 s
01:40:21.404077 WS.ttcn:245 Removing unterminated mapping between port p and system:p.
01:40:21.404107 WS.ttcn:245 Port p was unmapped from system:p.
01:40:21.404159 WS.ttcn:245 Port p was stopped.
01:40:21.404185 WS.ttcn:245 Component type WS.GeneralComp was shut down inside testcase TC_websocket.
01:40:21.404207 WS.ttcn:245 Waiting for PTCs to finish.
01:40:21.404647 WS.ttcn:245 Setting final verdict of the test case.
01:40:21.404895 WS.ttcn:245 Local verdict of MTC: pass
01:40:21.404935 WS.ttcn:245 No PTCs were created.
01:40:21.404965 WS.ttcn:245 Test case TC_websocket finished. Verdict: pass
01:40:21.405000 WS.ttcn:249 Execution of control part in module WS finished.
01:40:21.406109 - Verdict statistics: 0 none (0.00 %), 1 pass (100.00 %), 0 inconc (0.00 %), 0 fail (0.00 %), 0 error (0.00 %).
01:40:21.406207 - Test execution summary: 1 test case was executed. Overall verdict: pass
01:40:21.406229 - Exit was requested from MC. Terminating MTC.


For


WS.tsp_hostname:="www.websocket.org" 
WS.tsp_url:="/echo"
WS.tsp_use_ssl:=true



the only difference in the logs in non-debug mode is the establishment of connection(TLS instead of TCP):

01:57:05.792709 WS.ttcn:153 entering f__IPL4__PROVIDER__connect: :0 -> www.websocket.org:443 / SSL




I hope this will be of help to anyone willing to use websocket from Titan.


Best regards
Elemer



  • Attachment: WebSocket.tgz
    (Size: 725.91KB, Downloaded 125 times)
Re: Support for WebSocket in Eclipse Titan [message #1864595 is a reply to message #1767903] Wed, 27 March 2024 16:23 Go to previous messageGo to next message
Erwan Toux is currently offline Erwan TouxFriend
Messages: 6
Registered: March 2024
Junior Member
Hello Elemer,

I would like to use websocket for some of my own tests. I've been trying to use your example and I am struggling to compile the project.
I faced the issue 1. described here https://www.eclipse.org/forums/index.php?t=msg&th=1074584&goto=1773050&#msg_1773050 by adding the -e flag to the compiler, as you suggested to do.
However I am now facing another issue for which I didn't find any resource or similar problems :


~/test/ttcn3_test/websocket_test/bin » make
/home/erwant/.TITAN/titan.core/Install/bin/compiler -L -e  \
General_Types.ttcn HTTP_MessageLen.ttcn HTTP_Types.ttcn IPL4asp_PortType.ttcn IPL4asp_Types.ttcn Socket_API_Definitions.ttcn WebSocket_Types.ttcn WS.ttcn  - General_Types.ttcn HTTP_MessageLen.ttcn HTTP_Types.ttcn IPL4asp_PortType.ttcn IPL4asp_Types.ttcn Socket_API_Definitions.ttcn WebSocket_Types.ttcn WS.ttcn
Notify: Parsing TTCN-3 module `General_Types.ttcn'...
Notify: Parsing TTCN-3 module `HTTP_MessageLen.ttcn'...
Notify: Parsing TTCN-3 module `HTTP_Types.ttcn'...
Notify: Parsing TTCN-3 module `IPL4asp_PortType.ttcn'...
Notify: Parsing TTCN-3 module `IPL4asp_Types.ttcn'...
Notify: Parsing TTCN-3 module `Socket_API_Definitions.ttcn'...
Notify: Parsing TTCN-3 module `WebSocket_Types.ttcn'...
Notify: Parsing TTCN-3 module `WS.ttcn'...
Notify: Checking modules...
Notify: Generating code...
Notify: File `General_Types.hh' was generated.
Notify: File `General_Types.cc' was generated.
Notify: File `HTTP_MessageLen.hh' was generated.
Notify: File `HTTP_MessageLen.cc' was generated.
Notify: File `HTTP_Types.hh' was generated.
Notify: File `HTTP_Types.cc' was generated.
Notify: File `IPL4asp_PortType.hh' was generated.
Notify: File `IPL4asp_PortType.cc' was generated.
Notify: File `IPL4asp_Types.hh' was generated.
Notify: File `IPL4asp_Types.cc' was generated.
Notify: File `Socket_API_Definitions.hh' was generated.
Notify: File `Socket_API_Definitions.cc' was generated.
Notify: File `WS.hh' was generated.
Notify: File `WS.cc' was generated.
Notify: File `WebSocket_Types.hh' was generated.
Notify: File `WebSocket_Types.cc' was generated.
Notify: 16 files were updated.
touch compile
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o General_Types.o General_Types.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o HTTP_MessageLen.o HTTP_MessageLen.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o HTTP_Types.o HTTP_Types.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o IPL4asp_PortType.o IPL4asp_PortType.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o IPL4asp_Types.o IPL4asp_Types.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o Socket_API_Definitions.o Socket_API_Definitions.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o WebSocket_Types.o WebSocket_Types.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o WS.o WS.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o HTTP_EncDec.o HTTP_EncDec.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o HTTP_MessageLen_Function.o HTTP_MessageLen_Function.cc
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o IPL4asp_PT.o IPL4asp_PT.cc
IPL4asp_PT.cc: In member function 'virtual void IPL4asp__PortType::IPL4asp__PT_PROVIDER::set_parameter(const char*, const char*)':
IPL4asp_PT.cc:825:4: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
  825 |    if (!strcasecmp(parameter_value,"YES"))
      |    ^~
IPL4asp_PT.cc:827:7: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
  827 |       globalConnOpts.sctp_nodelay = GlobalConnOpts::YES;
      |       ^~~~~~~~~~~~~~
IPL4asp_PT.cc: In member function 'int IPL4asp__PortType::IPL4asp__PT_PROVIDER::ConnAdd(IPL4asp__PortType::SockType, int, IPL4asp__PortType::SSL_TLS_Type, const IPL4asp__Types::OptionList*, int)':
IPL4asp_PT.cc:3389:13: warning: 'void* memset(void*, int, size_t)' clearing an object of type 'struct IPL4asp__PortType::SockDesc' with no trivial copy-assignment; use assignment or value-initialization instead [-Wclass-memaccess]
 3389 |       memset(sockList + i, 0, sizeof (sockList[i]));
      |       ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from IPL4asp_PT.cc:32:
IPL4asp_PT.hh:202:16: note: 'struct IPL4asp__PortType::SockDesc' declared here
  202 | typedef struct {
      |                ^
g++  -c -DLINUX -I/home/erwant/.TITAN/titan.core/Install/include -Wall   -o WebSocket_EncDec.o WebSocket_EncDec.cc
if g++   -o websocket General_Types.o HTTP_MessageLen.o HTTP_Types.o IPL4asp_PortType.o IPL4asp_Types.o Socket_API_Definitions.o WebSocket_Types.o WS.o HTTP_EncDec.o HTTP_MessageLen_Function.o IPL4asp_PT.o WebSocket_EncDec.o \
-L/home/erwant/.TITAN/titan.core/Install/lib -lttcn3 \
-L/lib -lcrypto \
-L/home/erwant/.TITAN/titan.core/Install/lib -lxml2 -lpthread; \
then : ; else /home/erwant/.TITAN/titan.core/Install/bin/titanver General_Types.o HTTP_MessageLen.o HTTP_Types.o IPL4asp_PortType.o IPL4asp_Types.o Socket_API_Definitions.o WebSocket_Types.o WS.o HTTP_EncDec.o HTTP_MessageLen_Function.o IPL4asp_PT.o WebSocket_EncDec.o; exit 1; fi
/usr/bin/ld : HTTP_Types.o : in function « HTTP__Types::pre_init_module() » :
HTTP_Types.cc:(.text+0x61807) : undefined reference to « HTTP__Types::ef__HTTP__Decode(OCTETSTRING const&, BOOLEAN const&) »
/usr/bin/ld : WS.o : in function « WS::testcase_TC__websocket(bool, double) » :
WS.cc:(.text+0x1887) : undefined reference to « HTTP__Types::ef__HTTP__Decode(OCTETSTRING const&, BOOLEAN const&) »
collect2: error: ld returned 1 exit status
make: *** [Makefile:134 : websocket] Error 1



Sorry as this is kind of ugly to post but I have no idea on how to progress. Any clue on what could I do ?
Best regards,
Erwan
Re: Support for WebSocket in Eclipse Titan [message #1864663 is a reply to message #1864595] Tue, 02 April 2024 13:57 Go to previous messageGo to next message
Gábor Szalai is currently offline Gábor SzalaiFriend
Messages: 133
Registered: December 2015
Senior Member
Hi,

Did you use the Makefile from the tgz?
It seems to me that the HTTP_parse_tab.c and lex.HTTP_parse_.c are not compiled into the project. Please add them to the project, but please be careful that compile them with g++ not gcc.
Re: Support for WebSocket in Eclipse Titan [message #1864689 is a reply to message #1864663] Wed, 03 April 2024 12:25 Go to previous message
Erwan Toux is currently offline Erwan TouxFriend
Messages: 6
Registered: March 2024
Junior Member
Hello,

Thank you indeed they were both missing in the bin directory.
Problem solved thanks again!
Previous Topic:Re-usability of type filters to match received messages
Next Topic:Launching execute from config file with different parameters
Goto Forum:
  


Current Time: Thu Apr 25 19:15:32 GMT 2024

Powered by FUDForum. Page generated in 0.02996 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top