Transceiver52M: Reduce and place bounds checking on I/O buffers

Previous send and receive buffers at the radio interface were
arbitrarily set to a sufficient size. For normal (non-resampling)
devices, use a block (chunk) size of 625 samples. For 64 or 100
MHz resampling devices, use 4 times the reduced resampling
numerator or denominator and provide bounds checking where
appropriate.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
diff --git a/Transceiver52M/radioInterfaceResamp.cpp b/Transceiver52M/radioInterfaceResamp.cpp
index f857df9..c3b4396 100644
--- a/Transceiver52M/radioInterfaceResamp.cpp
+++ b/Transceiver52M/radioInterfaceResamp.cpp
@@ -36,6 +36,9 @@
 #define RESAMP_100M_INRATE			52
 #define RESAMP_100M_OUTRATE			75
 
+/* Universal resampling parameters */
+#define NUMCHUNKS				24
+
 /*
  * Resampling filter bandwidth scaling factor
  *   This narrows the filter cutoff relative to the output bandwidth
@@ -116,6 +119,11 @@
 	resamp_inchunk = resamp_inrate * 4;
 	resamp_outchunk = resamp_outrate * 4;
 
+	if (resamp_inchunk  * NUMCHUNKS < 157 * mSPSTx * 2) {
+		LOG(ALERT) << "Invalid inner chunk size " << resamp_inchunk;
+		return false;
+	}
+
 	if (mSPSTx == 4)
 		cutoff = RESAMP_TX4_FILTER;
 
@@ -137,16 +145,17 @@
 	 * and requires headroom equivalent to the filter length. Low
 	 * rate buffers are allocated in the main radio interface code.
 	 */
-	innerSendBuffer = new signalVector(resamp_inchunk * 20,
-					   upsampler->len());
-	outerSendBuffer = new signalVector(resamp_outchunk * 20);
+	innerSendBuffer =
+		new signalVector(NUMCHUNKS * resamp_inchunk, upsampler->len());
+	outerSendBuffer =
+		new signalVector(NUMCHUNKS * resamp_outchunk);
+	outerRecvBuffer =
+		new signalVector(resamp_outchunk, dnsampler->len());
+	innerRecvBuffer =
+		new signalVector(NUMCHUNKS * resamp_inchunk / mSPSTx);
 
-	outerRecvBuffer = new signalVector(resamp_outchunk * 2,
-					   dnsampler->len());
-	innerRecvBuffer = new signalVector(resamp_inchunk * 20);
-
-	convertSendBuffer = new short[resamp_outchunk * 2 * 20];
-	convertRecvBuffer = new short[resamp_outchunk * 2 * 2];
+	convertSendBuffer = new short[outerSendBuffer->size() * 2];
+	convertRecvBuffer = new short[outerRecvBuffer->size() * 2];
 
 	sendBuffer = innerSendBuffer;
 	recvBuffer = innerRecvBuffer;
@@ -159,35 +168,37 @@
 {
 	bool local_underrun;
 	int rc, num_recv;
-	int inner_len = resamp_inchunk;
-	int outer_len = resamp_outchunk;
+
+	if (recvCursor > innerRecvBuffer->size() - resamp_inchunk)
+		return;
 
 	/* Outer buffer access size is fixed */
 	num_recv = mRadio->readSamples(convertRecvBuffer,
-				       outer_len,
+				       resamp_outchunk,
 				       &overrun,
 				       readTimestamp,
 				       &local_underrun);
-	if (num_recv != outer_len) {
+	if (num_recv != resamp_outchunk) {
 		LOG(ALERT) << "Receive error " << num_recv;
 		return;
 	}
 
 	convert_short_float((float *) outerRecvBuffer->begin(),
-			    convertRecvBuffer, 2 * outer_len);
+			    convertRecvBuffer, 2 * resamp_outchunk);
 
 	underrun |= local_underrun;
-	readTimestamp += (TIMESTAMP) num_recv;
+	readTimestamp += (TIMESTAMP) resamp_outchunk;
 
 	/* Write to the end of the inner receive buffer */
-	rc = dnsampler->rotate((float *) outerRecvBuffer->begin(), outer_len,
+	rc = dnsampler->rotate((float *) outerRecvBuffer->begin(),
+			       resamp_outchunk,
 			       (float *) (innerRecvBuffer->begin() + recvCursor),
-			       inner_len);
+			       resamp_inchunk);
 	if (rc < 0) {
 		LOG(ALERT) << "Sample rate upsampling error";
 	}
 
-	recvCursor += inner_len;
+	recvCursor += resamp_inchunk;
 }
 
 /* Send a timestamped chunk to the device */
@@ -199,9 +210,10 @@
 	if (sendCursor < resamp_inchunk)
 		return;
 
+	if (sendCursor > innerSendBuffer->size())
+		LOG(ALERT) << "Send buffer overflow";
+
 	chunks = sendCursor / resamp_inchunk;
-	if (chunks > 8)
-		chunks = 8;
 
 	inner_len = chunks * resamp_inchunk;
 	outer_len = chunks * resamp_outchunk;