Commit edbf054a authored by Elemer Lelik's avatar Elemer Lelik
Browse files

update 20161117

parent f9321b07
/* Copyright (c) 2010, 2016 Ericsson AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Michael Josenhans
******************************************************************************/
//
// File: Isobus.ttcn
// Description: Encoder / Decoder for Isobus message frames
//
// Revision R1A
module Isobus {
import from General_Types all
import from Can all
import from IsobusMessageTypes all
import from IsobusCMMessageTypes all
import from IsobusNMMessageTypes all
import from IsobusVTMessageTypes all
// Note:
// SocketCAN Error frames are not considered here
// SocketCAN RTR frames are not considered here
// SocketCAN Basic frames are not considered here
external function encode_CAN_frame_j1939mod(in CAN_frame_j1939mod pdu) return octetstring
with { extension "prototype(convert) encode(RAW)" }
external function decode_CAN_frame_j1939mod(in octetstring data) return CAN_frame_j1939mod
with { extension "prototype(convert) decode(RAW)" }
const octetstring ISOBUS_PRIORITY_MASK := '1C000000'O;
const octetstring ISOBUS_RESERVED_MASK := '02000000'O;
const octetstring ISOBUS_DATAPAGE_MASK := '01000000'O;
const octetstring ISOBUS_PDUFORMAT_MASK := '00FF0000'O;
const octetstring ISOBUS_PDUSPECIFIC_MASK := '0000FF00'O;
const octetstring ISOBUS_SOURCEADDRESS_MASK := '000000FF'O;
//type BIT3 Priority
type bitstring Priority length(6)
with {
variant "ALIGN(left)";
variant "FIELDLENGTH(6)"
}
type record J1939 { // Error & RTR Frames are not considered here
//PGN pgn optional,
//BIT3 ignore,
Priority prio,
BIT1 res,
BIT1 dp,
OCT1 pf,
OCT1 ps,
SourceAddress sa
} with { variant "FIELDORDER(msb)" }
type record J1939mod { // Error & RTR Frames are not considered here
//PGN pgn optional,
//BIT3 ignore,
Priority prio,
BIT1 res,
BIT1 dp,
OCT1 pf,
OCT1 ps,
SourceAddress sa,
OCT3 comp
} with { variant "FIELDORDER(msb)" }
type union AnyIsoBusPdu {
TopLevelMessage_VT2ECU_PDU vt2ecu, // Message Virtual Terminal (VT) to ECU
TopLevelMessage_ECU2VT_PDU ecu2vt, // Message ECU to Virtual Terminal (VT)
RequestForAddressClaimed requestForAddressClaimed,
TP_DT tp_dt,
TP_CM tp_cm,
CannotClaimSourceAddress cannotClaimSourceAddress,
AddressClaimed addressClaimed,
CommandedAddress commandedAddress
// other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }
type record CAN_frame_j1939 {
J1939 can_j1939,
AnyIsoBusPdu can_pdu
}with {
variant (can_pdu) "CROSSTAG(
vt2ecu, can_j1939.pf = 'E6'O; //230
ecu2vt, can_j1939.pf = 'E7'O; //231
requestForAddressClaimed, can_j1939.pf = 'EA'O; //234
cannotClaimSourceAddress, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O, can_j1939.sa = 'FE'O}; //238 all and conjuction needed!!!!!!
addressClaimed, {can_j1939.pf = 'EE'O, can_j1939.ps = 'FF'O}; //238 all and conjuction needed!!!!!!
commandedAddress, {can_j1939.pf = 'FE'O, can_j1939.ps = 'D8'O})" //254 all and conjuction needed!!!!!!
}
type record CAN_frame_j1939mod {
J1939mod can_j1939,
AnyIsoBusPdu can_pdu
}with {
variant (can_pdu) "CROSSTAG(
vt2ecu, can_j1939.comp = 'E60000'O; //230
ecu2vt, can_j1939.comp = 'E70000'O; //231
requestForAddressClaimed, can_j1939.comp = 'EA0000'O; //234
tp_dt, can_j1939.comp = 'EB0000'O;
tp_cm, can_j1939.comp = 'EC0000'O;
cannotClaimSourceAddress, can_j1939.comp = 'EEFFFE'O; //238 all and conjuction needed!!!!!!
addressClaimed, can_j1939.comp = 'EEFF00'O; //238 all and conjuction needed!!!!!!
commandedAddress, can_j1939.comp = 'FED800'O)" //254 all and conjuction needed!!!!!!
}
//---------------------------------------------------------------------------------------
function j1939frame2can(in CAN_frame_j1939 p_can_frame_j1939, in Priority p_priority, in DestinationAddress p_da, in SourceAddress p_sa) return CAN_frame {
//---------------------------------------------------------------------------------------
var CAN_frame v_can_frame
v_can_frame.can_id := pdu1_j1939id2canid(p_can_frame_j1939.can_j1939, p_priority, p_da, p_sa)
// v_can_frame.can_pdu := encode_AnyIsoBusPdu(p_can_frame_j1939.can_pdu)
v_can_frame.can_pdu := substr(f_encode_CAN_frame_j1939(p_can_frame_j1939),0,3)//strip 3 byte header
return v_can_frame
}
function pdu1_j1939id2canid(in J1939 p_j1939, in Priority p_priority, in DestinationAddress p_da, in SourceAddress p_sa) return CAN_id{
var CAN_id v_can_id
v_can_id := bit2oct(oct2bit(p_sa) or4b (oct2bit(p_da) << 8) or4b (oct2bit(p_j1939.pf) << 16) or4b ((p_j1939.dp) << 24) or4b
((p_j1939.res) << 25) or4b (int2bit(bit2int(p_priority), 32) << 26))
return v_can_id
}
//---------------------------------------------------------------------------------------
function can2j1939frame(CAN_frame p_can_frame) return CAN_frame_j1939 {
//---------------------------------------------------------------------------------------
var CAN_frame_j1939 v_can_frame_j1939
log("can_id", p_can_frame.can_id)
log("can_pdu", p_can_frame.can_pdu)
v_can_frame_j1939:=f_decode_CAN_frame_j1939(p_can_frame.can_id& p_can_frame.can_pdu)
log("Higher layer octet pdustring: ", v_can_frame_j1939)
return v_can_frame_j1939
}
function canid2j1939(in CAN_id p_can_id) return J1939 {
var bitstring v_can_id_bitstring
var Priority v_priority
var BIT1 v_reserved // BIT1
var BIT1 v_datapage // BIT1
var OCT1 v_pduformat // OCT1
var OCT1 v_pduspecifc // OCT1
var OCT1 v_sourceaddress // OCT1
var PGN v_pgn
var J1939 v_j1939
v_can_id_bitstring := oct2bit(p_can_id)
v_priority := substr(v_can_id_bitstring, 3, 3)
v_reserved := v_can_id_bitstring[6]
v_datapage := v_can_id_bitstring[7]
v_pduformat := p_can_id[1] //(p_can_id and4b ISOBUS_PDUFORMAT_MASK) >> 2 // shift 16 bits = 2 octets
v_pduspecifc := p_can_id[2] // (p_can_id and4b ISOBUS_PDUSPECIFIC_MASK) >> 1 // shift 8 bits = 1 octet
v_sourceaddress := p_can_id[3] //(p_can_id and4b ISOBUS_SOURCEADDRESS_MASK)
if (oct2int(v_pduformat) < 240) {
v_pgn := bit2int(v_reserved)*2*256*256 + bit2int(v_datapage)*256 *256 + oct2int(v_pduformat)*256
} else {
v_pgn := bit2int(v_reserved)*2*256*256 + bit2int(v_datapage)*256 *256 + oct2int(v_pduformat)*256 + oct2int(v_pduspecifc)
}
v_j1939 := {/*pgn := v_pgn, */prio := v_priority, res := v_reserved, dp := v_datapage, pf := v_pduformat, ps := v_pduspecifc, sa := v_sourceaddress}
return v_j1939
}
//********************************************************************************-
//---------------------------------------------------------------------------
function f_insert_aux_hdr(in octetstring p_os) return octetstring
//---------------------------------------------------------------------------
{
var OCT3 v_os
v_os[0]:=p_os[1];//pf
if(p_os[1] == 'FE'O)
{
if (p_os[2]=='D8'O) {v_os[1]:='D8'O;v_os[2]:='00'O;}
}
else if(p_os[1] == 'EE'O)
{
if (p_os[2] == 'FF'O)
{ if (p_os[3]=='FE'O) {v_os[1]:='FF'O;v_os[2]:='FE'O;}
else {v_os[1]:='FF'O;v_os[2]:='00'O;}
}
}
else { v_os[1]:='00'O;v_os[2]:='00'O;}
//log("replace(p_os,4,0,v_os) :",replace(p_os,4,0,v_os))
return replace(p_os,4,0,v_os)//insert aux header
}
//---------------------------------------------------------------------------
function f_remove_aux_hdr(in octetstring p_os) return octetstring
//---------------------------------------------------------------------------
{
//log("p_os :",p_os)
p_os[1]:=p_os[4]; //pf := aux[0];
if (p_os[4] == 'EE'O)
{
if (p_os[6] == 'FE'O ) { //'EEFFFE' O
p_os[2]:=p_os[5]; //ps := aux[1];
p_os[3]:=p_os[6]; //sa := aux[2];
}
else { //'EEFFXX'O
p_os[2]:=p_os[5]; //ps := aux[1];
}
}
else if (p_os[4] == 'FE'O) //'FED8XX'O
{
p_os[2]:=p_os[5]; //ps := aux[1];
}
//log("p_os :",p_os)
//log("replace(p_os,4,3,''O) :",replace(p_os,4,3,''O))
return replace(p_os,4,3,''O); //remove aux header
}
//---------------------------------------------------------------------------
function f_map_mod2frame(in CAN_frame_j1939mod p_frame) return CAN_frame_j1939
//---------------------------------------------------------------------------
{
var CAN_frame_j1939 v_CAN_frame_j1939
v_CAN_frame_j1939.can_pdu:=p_frame.can_pdu;
v_CAN_frame_j1939.can_j1939.prio:=p_frame.can_j1939.prio;
v_CAN_frame_j1939.can_j1939.res:=p_frame.can_j1939.res;
v_CAN_frame_j1939.can_j1939.dp:=p_frame.can_j1939.dp;
v_CAN_frame_j1939.can_j1939.pf:=p_frame.can_j1939.pf;
v_CAN_frame_j1939.can_j1939.ps:=p_frame.can_j1939.ps;
v_CAN_frame_j1939.can_j1939.sa:=p_frame.can_j1939.sa;
//log("v_CAN_frame_j1939 :",v_CAN_frame_j1939)
return v_CAN_frame_j1939
}
//---------------------------------------------------------------------------
function f_map_frame2mod(in CAN_frame_j1939 p_frame) return CAN_frame_j1939mod
//---------------------------------------------------------------------------
{
var CAN_frame_j1939mod v_CAN_frame_j1939mod
v_CAN_frame_j1939mod.can_pdu:=p_frame.can_pdu;
v_CAN_frame_j1939mod.can_j1939.prio:=p_frame.can_j1939.prio;
v_CAN_frame_j1939mod.can_j1939.res:=p_frame.can_j1939.res;
v_CAN_frame_j1939mod.can_j1939.dp:=p_frame.can_j1939.dp;
v_CAN_frame_j1939mod.can_j1939.pf:=p_frame.can_j1939.pf;
v_CAN_frame_j1939mod.can_j1939.ps:=p_frame.can_j1939.ps;
v_CAN_frame_j1939mod.can_j1939.sa:=p_frame.can_j1939.sa;
if (p_frame.can_j1939.pf == 'EE'O)
{
if (p_frame.can_j1939.ps == 'D8'O) {
v_CAN_frame_j1939mod.can_j1939.comp := p_frame.can_j1939.pf&p_frame.can_j1939.ps&'00'O;
} else if (p_frame.can_j1939.ps == 'FF'O) {
if (p_frame.can_j1939.sa == 'FE'O) {
v_CAN_frame_j1939mod.can_j1939.comp := p_frame.can_j1939.pf&p_frame.can_j1939.ps&p_frame.can_j1939.sa
} else {//??
v_CAN_frame_j1939mod.can_j1939.comp:=p_frame.can_j1939.pf&'0000'O;
}
} else {//??
v_CAN_frame_j1939mod.can_j1939.comp:=p_frame.can_j1939.pf&'0000'O;
}
} else {
v_CAN_frame_j1939mod.can_j1939.comp := p_frame.can_j1939.pf&'0000'O;
}
//log("v_CAN_frame_j1939mod :",v_CAN_frame_j1939mod)
return v_CAN_frame_j1939mod;
}
//---------------------------------------------------------------------------
function f_encode_CAN_frame_j1939(in CAN_frame_j1939 pdu) return octetstring
//---------------------------------------------------------------------------
{
return f_remove_aux_hdr(encode_CAN_frame_j1939mod(f_map_frame2mod(pdu)))
}
//---------------------------------------------------------------------------
function f_decode_CAN_frame_j1939(in octetstring data) return CAN_frame_j1939
//---------------------------------------------------------------------------
{
return f_map_mod2frame(decode_CAN_frame_j1939mod(f_insert_aux_hdr(data)))
}
} with { encode "RAW" }
module IsobusCMMessageTypes {
import from General_Types all
import from IsobusMessageTypes all
type OCT1 Ctrl
type record RequestToSend{
Ctrl ctrl ('10'O),
INT2 msgSizeInByte,
INT1 totalNumberOfPackets,
INT1 maxNoOfPacketsInResponseToCTS,
PGN pgnOfMultiPacketMessage
} with { variant "" };
type record ClearToSend{
Ctrl ctrl ('11'O),
INT1 totalNumberOfPackets,
INT1 nextPacketNumber,
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
PGN pgnOfMultiPacketMessage
} with { variant "" };
type record EndOfMessageAcknowledgement{
Ctrl ctrl ('13'O),
INT2 msgSizeInByte,
INT1 totalNumberOfPackets,
OCT1 reserved5 ('FF'O),
PGN pgnOfMultiPacketMessage
} with { variant "" };
type record ConnectionAbort{
Ctrl ctrl ('FF'O),
OCT1 connectionAbortReason,
OCT1 reserved3 ('FF'O),
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
PGN pgnOfMultiPacketMessage
} with { variant "" };
type record BroadcastAnnonce{
Ctrl ctrl ('20'O),
INT2 msgSizeInByte,
INT1 totalNumberOfPackets,
OCT1 reserved5 ('FF'O),
PGN pgnOfMultiPacketMessage
} with { variant "" };
type union TP_CM
{
RequestToSend requestToSend,
ClearToSend clearToSend,
EndOfMessageAcknowledgement endOfMessageAcknowledgement,
BroadcastAnnonce broadcastAnnounce,
ConnectionAbort connectionAbort
}
with {variant "TAG (
// put all ECU2VT request messages here
requestToSend, ctrl = '10'O;
clearToSend, ctrl = '11'O;
endOfMessageAcknowledgement, ctrl = '13'O;
broadcastAnnounce, ctrl = '20'O;
connectionAbort, ctrl = 'FF'O;
) "
}
type record TP_DT{
INT1 seq_no,
OCT7 data
} with { variant "" }
} with { encode "RAW" }
/*
* Contributors:
* Michael Josenhans
*/
module IsobusMessageTypes {
type integer INT24nb (0..16777215) with { variant "FIELDLENGTH(24), COMP(nosign), BYTEORDER(last)" };
type INT24nb PGN
type integer INT2 (0..65535)
with { variant "FIELDLENGTH(16)" };
type integer INT3 (0..16777215)
with { variant "FIELDLENGTH(24)" };
}
with { encode "RAW" }
/*
* Contributors:
* Michael Josenhans
*/
module IsobusNMMessageTypes {
import from General_Types all
import from IsobusMessageTypes all
type OCT1 DestinationAddress
type OCT1 PDUFormat
type OCT1 SourceAddress
type OCT8 NAME
type record CannotClaimSourceAddress
{
NAME name
} with { variant "" }
type record AddressClaimed
{
NAME name
} with { variant "" }
type record RequestForAddressClaimed {
PGN pgn
} with { variant "" }
type record CommandedAddress {
NAME name,
SourceAddress newSourceAddress
} with { variant "" }
}with { encode "RAW" }
module IsobusVTMessageTypes {
import from General_Types all
import from IsobusMessageTypes all
type INT1 VTfunction
type record GetMemoryReq
{
VTfunction vtfunction (194),
OCT1 reserved2 ('FF'O),
INT3 memoryRequired,
OCT1 reserved7 ('FF'O),
OCT1 reserved8 ('FF'O)
} with { variant "" };
type enumerated e_GetMemoryResVersionNumber {
compliantWithHannoverAgritechnica_2001_limitedfeatureSet (0),
compliantWithFDISVersionISO11783_6_2002_E_Final_Draft (1),
compliantWithISVersionISO11783_6_2004_E_First_Edition (2),
compliantWithISVersionISO11783_6_2010_E_Second_Edition_version_3 (3),
compliantWithISVersionISO11783_6_2010_E_Second_Edition_version_4 (4),
compliantWithISVersionISO11783_6_2014_E_Third_Edition (5)}
with {variant "PADDING(octet)" };
type enumerated e_GetMemoryResStatus {
thereCanBeEnoughMemory (0),
thereIsNotEnoughMemoryAvailable (1)}
with {variant "PADDING(octet)" }
type record GetMemoryRes
{
VTfunction vtfunction (194),
e_GetMemoryResVersionNumber versionNumber,
e_GetMemoryResStatus status,
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
OCT1 reserved6 ('FF'O),
OCT1 reserved7 ('FF'O),
OCT1 reserved8 ('FF'O)
} with { variant "" };
type record GetNumberOfSoftKeysReq
{
VTfunction vtfunction (192),
OCT1 reserved2 ('FF'O),
OCT1 reserved3 ('FF'O),
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
OCT1 reserved6 ('FF'O),
OCT1 reserved7 ('FF'O),
OCT1 reserved8 ('FF'O)
} with { variant "" };
type record GetNumberOfSoftKeysRes
{
VTfunction vtfunction (192),
OCT1 navigationSoftKeys_,
OCT1 reserved3 ('FF'O),
OCT1 reserved4 ('FF'O),
OCT1 x_dots,
OCT1 y_dots,
OCT1 numberOfVirtualSoftKeys_,
OCT1 numberOfPhysicalSoftKeys_
} with { variant "" };
type record GetTextFontDataReq
{
VTfunction vtfunction (195),
OCT1 reserved2 ('FF'O),
OCT1 reserved3 ('FF'O),
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
OCT1 reserved6 ('FF'O),
OCT1 reserved7 ('FF'O),
OCT1 reserved8 ('FF'O)
} with { variant "" };
type enumerated e_TextFontDataRes_small_font_sizes {
font_6x8 (0),
font_8x8 (1),
font_8x12 (2),
font_12x16 (4),
font_16x16 (8),
font_16x24 (16),
font_24x32 (32),
font_32x32 (64),
reserved (128)
}
with {variant "PADDING(octet)" };
type enumerated e_TextFontDataRes_large_font_sizes {
font_32x48 (1),
font_48x64 (2),
font_64x64 (4),
font_64x96 (8),
font_96x128 (16),
font_128x128 (32),
font_128x192 (64),
reserved (128)
}
with {variant "PADDING(octet)" }
type enumerated e_TextFontDataRes_type_attribute {
normal_text (0),
bold_text (1),
crossed_out_text (2),
underlined_text (4),
italics_text (8),
inverted_text (16),
flash_inverted (32),
flash_background_and_foreground (64),
proportional_font_rendering_ (128)
}
with {variant "PADDING(octet)"}
type record GetTextFontDataRes
{
VTfunction vtfunction (195),
OCT1 reserved2 ('FF'O),
OCT1 reserved3 ('FF'O),
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
e_TextFontDataRes_small_font_sizes small_font_sizes,
e_TextFontDataRes_large_font_sizes large_font_sizes,
e_TextFontDataRes_type_attribute type_attribute
} with { variant "" };
type record GetHardwareReq
{
VTfunction vtfunction (199),
OCT1 reserved2 ('FF'O),
OCT1 reserved3 ('FF'O),
OCT1 reserved4 ('FF'O),
OCT1 reserved5 ('FF'O),
OCT1 reserved6 ('FF'O),
OCT1 reserved7 ('FF'O),
OCT1 reserved8 ('FF'O)
} with { variant "" };
type enumerated e_GetHardwareResGraphicType {
monochrome (0),
colors16 (1),
colors256 (2)
}
with {variant "PADDING(octet)"}
type record e_GetHardwareResHardware {
boolean touchScreenandPointingEvent,
boolean pointingDeviceAndPointingEvent,
boolean multipleFrequencyAudioOutput,