2222import java .util .logging .Level ;
2323
2424import com .cosylab .epics .caj .cas .CAJServerContext ;
25+ import com .cosylab .epics .caj .cas .CASTransport ;
2526import com .cosylab .epics .caj .cas .requests .SearchFailedRequest ;
2627import com .cosylab .epics .caj .cas .requests .SearchRequest ;
2728import com .cosylab .epics .caj .impl .CAConstants ;
@@ -49,20 +50,37 @@ protected void internalHandleResponse(
4950 Transport transport ,
5051 ByteBuffer [] response ) {
5152
52- ByteBuffer headerBuffer = response [0 ];
53- final int start = headerBuffer .position ();
53+ // For a UDP client, BroadcastTransport.processRead will call this with response=[buffer].
54+ // That one buffer holds version info, search header and search payload, positioned at start of payload:
55+ //
56+ // 00 00 00 00 00 01 00 0D 00 00 00 01 00 00 00 00 .... .... .... ....
57+ // 00 06 00 08 00 05 00 0D 00 00 00 01 00 00 00 01 .... .... .... ....
58+ // 54 45 53 54 00 00 00 00 TEST ....
59+ // ^^
60+ //
61+ // For a TCP client, CASTransport.processRead will call this with a response=[headerBuffer, payloadBuffer].
62+ // headerBuffer is positioned at the end, and a payloadBuffer positioned at the start:
63+ //
64+ // 00 06 00 08 00 05 00 0D 00 00 00 01 00 00 00 01 .... .... .... ....
65+ // ^^
66+ // 54 45 53 54 00 00 00 00 TEST ....
67+ // ^^
68+ // We need the payload, which holds the zero-padded channel name
69+ ByteBuffer buffer = response .length == 2 ? response [1 ] : response [0 ];
70+
71+ final int start = buffer .position ();
5472 final int bufferEnd = start + payloadSize ;
5573
5674 // to support multiple messages in one UDP packet
57- headerBuffer .position (bufferEnd );
75+ buffer .position (bufferEnd );
5876
5977 // check channel name size
6078 if (payloadSize <= 1 ) {
6179 context .getLogger ().fine ("Empty channel name search request from: " + responseFrom );
6280 return ;
6381 }
6482
65- String channelName = extractString (headerBuffer , start , payloadSize , false );
83+ String channelName = extractString (buffer , start , payloadSize , false );
6684
6785 // empty name check
6886 if (channelName .length () == 0 ) {
@@ -92,8 +110,9 @@ protected void internalHandleResponse(
92110 if (completion == ProcessVariableExistanceCompletion .EXISTS_HERE ||
93111 completion == ProcessVariableExistanceCompletion .DOES_NOT_EXIST_HERE ||
94112 completion .doesExistElsewhere ())
95- {
96- searchResponse (responseFrom , dataType , dataCount , parameter1 , completion );
113+ { // Reply via TCP?
114+ CASTransport tcp = transport instanceof CASTransport ? (CASTransport ) transport : null ;
115+ searchResponse (responseFrom , tcp , dataType , dataCount , parameter1 , completion );
97116 }
98117 // in case of ProcessVariableExistanceCompletion.ASYNC_COMPLETION callback will call searchResponse method
99118 // in case of null, do nothing
@@ -102,12 +121,13 @@ protected void internalHandleResponse(
102121 /**
103122 * Respond to search response.
104123 * @param responseFrom
124+ * @param tcp Use TCP CASTransport?
105125 * @param dataType
106126 * @param dataCount
107127 * @param cid
108128 * @param completion
109129 */
110- private void searchResponse (InetSocketAddress responseFrom , short dataType , int dataCount , int cid , ProcessVariableExistanceCompletion completion ) {
130+ private void searchResponse (InetSocketAddress responseFrom , CASTransport tcp , short dataType , int dataCount , int cid , ProcessVariableExistanceCompletion completion ) {
111131
112132 //
113133 // ... respond
@@ -118,20 +138,40 @@ private void searchResponse(InetSocketAddress responseFrom, short dataType, int
118138 try
119139 {
120140 // TODO prepend version header (if context.getLastReceivedSequenceNumber() != 0)
121- SearchRequest searchRequest = new SearchRequest (context .getBroadcastTransport (), (short )dataCount , cid );
122- context .getBroadcastTransport ().send (searchRequest , responseFrom );
141+ // UDP includes payload (version) in reply, TCP has no payload
142+ if (tcp == null )
143+ {
144+ SearchRequest searchRequest = new SearchRequest (context .getBroadcastTransport (), null , true , (short )dataCount , cid );
145+ context .getLogger ().log (Level .FINE , "UDP EXISTS_HERE search reply" );
146+ context .getBroadcastTransport ().send (searchRequest , responseFrom );
147+ }
148+ else
149+ {
150+ SearchRequest searchRequest = new SearchRequest (context .getBroadcastTransport (), null , false , (short )dataCount , cid );
151+ context .getLogger ().log (Level .FINE , "TCP EXISTS_HERE search reply" );
152+ tcp .send (searchRequest .getRequestMessage ());
153+ }
123154 } catch (Throwable th ) {
124155 context .getLogger ().log (Level .WARNING , "Failed to send back search response to: " + responseFrom , th );
125156 }
126157 }
127158 else if (completion .doesExistElsewhere ())
128159 {
129- // send back
160+ // Same comments as for EXISTS_HERE
130161 try
131162 {
132- // TODO prepend version header (if context.getLastReceivedSequenceNumber() != 0)
133- SearchRequest searchRequest = new SearchRequest (context .getBroadcastTransport (), completion .getOtherAddress (), (short )dataCount , cid );
134- context .getBroadcastTransport ().send (searchRequest , responseFrom );
163+ if (tcp == null )
164+ {
165+ SearchRequest searchRequest = new SearchRequest (context .getBroadcastTransport (), completion .getOtherAddress (), true , (short )dataCount , cid );
166+ context .getLogger ().log (Level .FINE , "UDP EXISTS_ELSEWHERE search reply: " + completion .getOtherAddress ());
167+ context .getBroadcastTransport ().send (searchRequest , responseFrom );
168+ }
169+ else
170+ {
171+ SearchRequest searchRequest = new SearchRequest (context .getBroadcastTransport (), completion .getOtherAddress (), false , (short )dataCount , cid );
172+ context .getLogger ().log (Level .FINE , "TCP EXISTS_ELSEWHERE search reply: " + completion .getOtherAddress ());
173+ tcp .send (searchRequest .getRequestMessage ());
174+ }
135175 } catch (Throwable th ) {
136176 context .getLogger ().log (Level .WARNING , "Failed to send back search response to: " + responseFrom , th );
137177 }
@@ -197,7 +237,7 @@ public ProcessVariableExistanceCallbackImpl(InetSocketAddress responseFrom,
197237 * @see gov.aps.jca.cas.ProcessVariableExistanceCallback#processVariableExistanceTestCompleted(gov.aps.jca.cas.ProcessVariableExistanceCompletion)
198238 */
199239 public void processVariableExistanceTestCompleted (ProcessVariableExistanceCompletion completion ) {
200- searchResponse (responseFrom , dataType , dataCount , cid , completion );
240+ searchResponse (responseFrom , null /* not TCP */ , dataType , dataCount , cid , completion );
201241 }
202242
203243 /* (non-Javadoc)
0 commit comments