1 | %------------------------------------------------------------------------- |
---|
2 | % WARPLab Framework |
---|
3 | % |
---|
4 | % Copyright 2013, Mango Communications. All rights reserved. |
---|
5 | % Distributed under the WARP license (http://warpproject.org/license) |
---|
6 | % |
---|
7 | % Chris Hunter (chunter [at] mangocomm.com) |
---|
8 | % Patrick Murphy (murphpo [at] mangocomm.com) |
---|
9 | % Erik Welsh (welsh [at] mangocomm.com) |
---|
10 | %------------------------------------------------------------------------- |
---|
11 | |
---|
12 | classdef wl_transport_header < wl_msg_helper |
---|
13 | % Contains data needed by the transport to ensure reliable transmission |
---|
14 | |
---|
15 | properties(Hidden = true, Constant = true) |
---|
16 | PKTTYPE_TRIGGER = uint8(0); |
---|
17 | PKTTYPE_HTON_MSG = uint8(1); |
---|
18 | PKTTYPE_NTOH_MSG = uint8(2); |
---|
19 | ROBUST_FLAG = uint16(1); % Value of 0x0001 |
---|
20 | NODE_NOT_READY_FLAG = uint16(32768); % Value of 0x8000 |
---|
21 | end |
---|
22 | |
---|
23 | properties(SetAccess = public, Hidden = true) |
---|
24 | seqNum = uint16(0); % Sequence number for outgoing transmissions |
---|
25 | reserved = uint8(0); |
---|
26 | end |
---|
27 | |
---|
28 | properties (SetAccess = public) |
---|
29 | flags = uint16(0); |
---|
30 | msgLength = uint16(0); |
---|
31 | destID = uint16(0); % Destination ID for outgoing transmissions |
---|
32 | srcID = uint16(0); % Source ID for outgoing transmissions |
---|
33 | pktType = uint8(0); |
---|
34 | end |
---|
35 | |
---|
36 | methods |
---|
37 | function obj = wl_transport_header() |
---|
38 | % Sets the default data type of the header to be 'uint32' and initializes sequence number to 0. |
---|
39 | % |
---|
40 | obj.seqNum = 0; |
---|
41 | end |
---|
42 | |
---|
43 | function len = length(obj) |
---|
44 | % Returns the header length in # of uint32s. |
---|
45 | % |
---|
46 | len = 3; % NOTE: This needs to match the actual u32 length |
---|
47 | % NOTE: We are returning a constant b/c the transport header doesn't change length |
---|
48 | end |
---|
49 | |
---|
50 | function out = sizeof(obj) |
---|
51 | out = (length(obj) * 4); |
---|
52 | end |
---|
53 | |
---|
54 | function reset(obj) |
---|
55 | % Resets the sequence number back to 1. |
---|
56 | % |
---|
57 | obj.seqNum = 1; |
---|
58 | end |
---|
59 | |
---|
60 | function increment(obj, varargin) |
---|
61 | % Increments the sequence number. |
---|
62 | % |
---|
63 | if( nargin == 1 ) |
---|
64 | if(obj.seqNum ~= uint16(realmax)) |
---|
65 | obj.seqNum = obj.seqNum + 1; |
---|
66 | else |
---|
67 | obj.seqNum = 0; |
---|
68 | end |
---|
69 | else |
---|
70 | obj.seqNum = mod( (obj.seqNum + varargin{1}), uint16(realmax) ); |
---|
71 | end |
---|
72 | end |
---|
73 | |
---|
74 | function output = deserialize(obj) |
---|
75 | % Un-used for transport_headers |
---|
76 | end |
---|
77 | |
---|
78 | function output = serialize(obj) |
---|
79 | % Serializes the header to a vector of uint32 items |
---|
80 | % This function serializes the header to a vector for placing into outgoing packets by |
---|
81 | % wl_transport's children. The structure of the transport header is: |
---|
82 | % typedef struct { |
---|
83 | % u16 destID; |
---|
84 | % u16 srcID; |
---|
85 | % u8 reserved; |
---|
86 | % u8 pktType; |
---|
87 | % u16 length; |
---|
88 | % u16 seqNum; |
---|
89 | % u16 flags; |
---|
90 | % } wl_transport_header; |
---|
91 | % NOTE: Calling cast(x,'uint32') is much slower than uint32(2) |
---|
92 | % Bitshift/bitor are slower than explicit mults/adds |
---|
93 | % |
---|
94 | w0 = (2^16 * uint32(obj.destID)) + uint32(obj.srcID); |
---|
95 | w1 = (2^24 * uint32(obj.reserved)) + (2^16 * uint32(obj.pktType)) + uint32(obj.msgLength); |
---|
96 | w2 = (2^16 * uint32(obj.seqNum)) + uint32(obj.flags); |
---|
97 | output = [w0 w1 w2]; |
---|
98 | end |
---|
99 | |
---|
100 | function match = isReply(obj, input) |
---|
101 | % Checks an input vector to see if it is a valid reply to the last outgoing packet. |
---|
102 | % This function checks to make sure that the received source address matches |
---|
103 | % the previously sent destination addresses and makes sure that the sequence numbers match. |
---|
104 | % |
---|
105 | try |
---|
106 | src_dest = ((2^16 * obj.srcID) + obj.destID); |
---|
107 | reply_seq = bitshift(input(3), -16); |
---|
108 | |
---|
109 | match = min([(input(1) == src_dest), (reply_seq == obj.seqNum)]); |
---|
110 | |
---|
111 | if(match == 0) |
---|
112 | reply_dest = bitand(65535, input(1)); |
---|
113 | reply_src = bitshift(input(1), -16); |
---|
114 | |
---|
115 | warning('wl_transport_header:setType', 'transport_header mismatch: [%d %d] [%d %d] [%d %d]\n',... |
---|
116 | reply_src, obj.srcID, reply_dest, obj.destID, reply_seq, obj.seqNum); |
---|
117 | end |
---|
118 | catch receiveError |
---|
119 | error('wl_transport_header:isReply',sprintf('Length of header not correct. Received %d words needed %d', length(input), obj.length())) |
---|
120 | end |
---|
121 | end |
---|
122 | |
---|
123 | function ready = isNodeReady(obj, input) |
---|
124 | % Checks an input vector to see if the node has set the TRANSPORT_HDR_NODE_NOT_READY_FLAG bit |
---|
125 | % |
---|
126 | if(length(input) == length(obj.serialize)) |
---|
127 | ready = ~(uint16(bitand(uint16(bitand(65535, input(3))), obj.NODE_NOT_READY_FLAG)) == obj.NODE_NOT_READY_FLAG); |
---|
128 | else |
---|
129 | error('wl_transport_header:setType',sprintf('length of header did not match internal length of %d', obj.type)) |
---|
130 | end |
---|
131 | end |
---|
132 | |
---|
133 | end %methods |
---|
134 | end %classdef |
---|