BowlerKernel
BowlerDatagramFactory.java
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright 2010 Neuron Robotics, LLC
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  ******************************************************************************/
15 package com.neuronrobotics.sdk.common;
16 
17 // TODO: Auto-generated Javadoc
25 public class BowlerDatagramFactory {
26 
29 
31  private static BowlerDatagram pool [];
32 
34  private static int failed=0;
35 
37  private static int lastIndex = 0;
38 
40  private static int poolDefaultSize = 1000;
41 
43  private static long packetTimeout = 5000;
44 
45  static{
46  if(instance == null){
48  pool = new BowlerDatagram[getDefaultPoolSize()];
49  for (int i=0;i<getDefaultPoolSize();i++){
50  pool [i] = new BowlerDatagram(instance);
51  freePacket(pool [i]);
52  }
53  }
54  }
55 
61  public static int getCurrentPoolSize(){
62  return pool.length;
63  }
64 
71  public static boolean validateFactory(BowlerDatagramFactory test){
72  if(test == instance){
73  return true;
74  }
75  throw new RuntimeException("Invalid factory generation of packet. Use BowlerDatagramFactory.getNextPacket()");
76  }
77 
83  private static BowlerDatagram getNextPacket(){
84  BowlerDatagram ref = new BowlerDatagram(instance);
85 
86  //Find the most recent free packet from the pool
87 // for(int i=lastIndex;(i<pool.length && ref==null);i++){
88 // //Log.warning("Checking pool packet "+i);
89 // if(pool[i]==null){
90 // pool[i]=new BowlerDatagram(instance);
91 // }
92 // freePacket(pool[i]);
93 // if(pool[i].isFree()){
94 // lastIndex=i;
95 // ref=pool[i];
96 // }
97 // if(i==pool.length-1 && ref==null){
98 // //loop around since we started at the last index
99 // i=0;
100 // }
101 // if(i==lastIndex-1 && ref==null){
102 // //looped around, bail
103 // i=pool.length;
104 // }
105 // if(ref!=null){
106 // lastIndex=i++;
107 // }
108 // }
109 // if(ref == null){
110 // //The whole list was search and no free packets were found
111 // //pool= new BowlerDatagram[(int) ((float)pool.length)];
112 // //Log.warning("Resetting pool "+pool.length);
113 // //pool[0]= new BowlerDatagram(instance);
114 // ref=pool[0];
115 // }
116  //old pool data given to the GC
117  ref.setFree(false,instance);
118  return ref;
119  }
120 
126  public static void freePacket(BowlerDatagram bd){
127  bd.setFree(true, instance);
128  }
129 
137  //public static final byte REVISION = BowlerDatagram.REVISION;
138 
147  public static BowlerDatagram build(MACAddress addr, BowlerAbstractCommand cmd) {
148  BowlerDatagram bd = getNextPacket();
149  long start = System.currentTimeMillis();
150 
151  if (addr== null)
152  addr = new MACAddress();
153  try{
154  bd.setAddress(addr);
155  bd.setMethod(cmd.getMethod()); // method id
156  bd.setNamespaceResolutionID((byte) cmd.getNamespaceIndex());// Rpc Index id
157  bd.setData(cmd.getBytes());
158  bd.calcCRC();
159  }catch(Exception e){
160  e.printStackTrace();
161  //if(System.currentTimeMillis()>(start+BowlerDatagramFactory.getPacketTimeout()))
162  Log.error("Timeout detected, duration = "+(System.currentTimeMillis()-start)+", expected = "+BowlerDatagramFactory.getPacketTimeout());
163  }
164  bd.setFree(false,instance);
165  return bd;
166  }
167 
174  public static BowlerDatagram build(ByteList buffer ){
175  BowlerDatagram buff= getNextPacket();
176  buff.setFree(false,instance);
177  BowlerDatagram ret = build(buffer, buff );
178  if(ret == null)
179  freePacket(buff);
180  return ret;
181  }
182 
190  private static BowlerDatagram build(ByteList buffer, BowlerDatagram staticMemory){
191  if((buffer.size()==0))
192  return null;
193  byte fb;
194  try{
195  fb = buffer.get(0);
196  }catch (Exception e){
197  Log.warning("Datagram builder first byte warning: "+e.getMessage());
198  return null;
199  }
200 
201  while(fb!=BowlerDatagram.REVISION) {
202  //Log.error("First Byte Fail, Junk byte: "+String.format("%02x ", buffer.pop()));
203  failed++;
204  try{
205  if(buffer.size()==0){
206  if(failed>0){
207  //Log.error("Failed out "+failed+" bytes");
208  }
209  return null;
210  }
211  fb = buffer.get(0);
212  }catch (Exception e){
213  Log.warning("Datagram builder warning: "+e.getMessage());
214  if(failed>0){
215  //Log.error("Failed out "+failed+" bytes");
216  }
217  return null;
218  }
219  }
220 
221 
222  if(buffer.size()<BowlerDatagram.HEADER_SIZE)
223  return null;
224  boolean check = false;
225  while(check==false) {
226  try{
227  if( (buffer.get(0) != BowlerDatagram.REVISION)
228  || (!BowlerDatagram.CheckCRC(buffer,false))){
229  if(buffer.get(0) != BowlerDatagram.REVISION)
230  Log.error("First Byte Fail (second attempt) Junk byte: "+String.format("%02x ", buffer.pop()));
231  else
232  Log.error("CRC check Fail (second attempt) Junk byte: "+String.format("%02x ", buffer.pop()));
233  failed++;
234  }else{
235  check=true;
236  }
237  }catch (Exception e){
238  //Log.error("Datagram builder error: "+e.getMessage());
239  if(failed>0){
240  //Log.error("Failed out "+failed+" bytes");
241  }
242  e.printStackTrace();
243  return null;
244  }
245  if (buffer.size()<BowlerDatagram.HEADER_SIZE) {
246  if(failed>0){
247  //Log.error("Failed out "+failed+" bytes");
248  }
249  return null;//Not enough bytes to even be a header, try back later
250  }
251  }
252  int len =buffer.getUnsigned(9);
253 
254  if(len<4){
255  Log.error("#*#*Warning, packet has no RPC, size: "+len);
256  }
257  int totalLen = len+BowlerDatagram.HEADER_SIZE;
258 
259  if(BowlerDatagram.isUseBowlerV4())
260  totalLen+=1;
261  staticMemory.setFree(false,instance);
262  // See if all the data has arrived for this packet
263  if (buffer.size()>=(totalLen)){
264  failed=0;
265  ByteList rawContent = new ByteList(buffer.popList(totalLen));
266  try{
267  staticMemory.parse(rawContent);
268  return staticMemory;
269  }catch(MalformattedDatagram m){
270  Log.error("Data CRC check Fail "+staticMemory);
271  failed = rawContent.size();
272  throw m;
273  }
274  }
275 // if(failed>0)
276 // Log.error("Failed out "+failed+" bytes");
277  return null;
278  }
279 
285  public static int getDefaultPoolSize() {
286  return poolDefaultSize;
287  }
288 
294  public static void setPoolSize(int poolSize) {
295  BowlerDatagramFactory.poolDefaultSize = poolSize;
296  }
297 
303  public static long getPacketTimeout() {
304  return packetTimeout;
305  }
306 
312  public static void setPacketTimeout(int packetTimeout) {
313  BowlerDatagramFactory.packetTimeout = packetTimeout;
314  }
315 
316 }