add some tools for dealing with the audio

Change-Id: I42ca6001399326cdddbea6bcfca0f46bcb8209bc
diff --git a/gfiber-tools/RAS_lib.h b/gfiber-tools/RAS_lib.h
new file mode 100644
index 0000000..cfdacdb
--- /dev/null
+++ b/gfiber-tools/RAS_lib.h
@@ -0,0 +1,164 @@
+/**************************************************************************************************

+  Filename:       RAS_lib.h

+

+  Description:    RemoTI Audio Subsystem Library

+

+

+  Copyright 2013 Texas Instruments Incorporated. All rights reserved.

+

+  IMPORTANT: Your use of this Software is limited to those specific rights

+  granted under the terms of a software license agreement between the user

+  who downloaded the software, his/her employer (which must be your employer)

+  and Texas Instruments Incorporated (the "License").  You may not use this

+  Software unless you agree to abide by the terms of the License. The License

+  limits your use, and you acknowledge, that the Software may not be modified,

+  copied or distributed unless embedded on a Texas Instruments microcontroller

+  or used solely and exclusively in conjunction with a Texas Instruments radio

+  frequency transceiver, which is integrated into your product.  Other than for

+  the foregoing purpose, you may not use, reproduce, copy, prepare derivative

+  works of, modify, distribute, perform, display or sell this Software and/or

+  its documentation for any purpose.

+

+  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE

+  PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,

+  INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,

+  NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL

+  TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,

+  NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER

+  LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES

+  INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE

+  OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT

+  OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES

+  (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

+

+  Should you have any questions regarding your right to use this Software,

+  contact Texas Instruments Incorporated at www.TI.com.

+**************************************************************************************************/

+

+

+#ifndef RSA_LIB_H

+#define RSA_LIB_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+

+/////////////////////////////////////////////////////////////////////////////

+// Defines

+

+#define MAX_INPUT_BUF_SIZE 		128

+

+#define RAS_PACKET_LOST 		0

+#define RAS_DECODE_TI_TYPE1		1

+

+#define RAS_NO_PEC		   		0

+#define RAS_PEC_MODE1   		1

+

+//RAS Software Version: v0.7

+#define RAS_SOFTWARE_VERSION	0x0007

+/////////////////////////////////////////////////////////////////////////////

+// Typedefs

+#ifndef int8

+typedef signed   char   int8;

+#endif

+

+#ifndef uint8

+typedef unsigned char   uint8;

+#endif

+

+#ifndef int16

+typedef signed   short  int16;

+#endif

+

+#ifndef uint16

+typedef unsigned short  uint16;

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+// Global variable

+

+

+/////////////////////////////////////////////////////////////////////////////

+// Function declarations

+/**************************************************************************************************

+ *

+ * @fn      RAS_GetVersion

+ *

+ * @brief   RemoTI Audio Subsystem, retrieve software version

+ *

+ * input parameters

+ *

+ * none

+ *

+ * output parameters

+ *

+ * None.

+ *

+ * @return      .

+ * Software Version.	MSB	 Major revision number

+ *						LSB: Minor revision number

+ */

+extern uint16 RAS_GetVersion( void );

+

+/**************************************************************************************************

+ *

+ * @fn      RAS_Init

+ *

+ * @brief   RemoTI Audio Subsystem, initialization function

+ *

+ * input parameters

+ *

+ * @param   pec_mode:    	Packet Error concealment algorithm to apply:

+ * 							RAS_NO_PEC(0): 		None (default)

+ * 							RAS_PEC_MODE1(1): 	Replace lost packets by last valid.

+ *

+ * output parameters

+ *

+ * None.

+ *

+ * @return      .

+ * status.	0				SUCCESS

+ * 			-1				ERROR: INVALID PARAMETER

+ */

+extern uint8 RAS_Init( uint8 pec_mode );

+

+

+/**************************************************************************************************

+ *

+ * @fn      RAS_Decode

+ *

+ * @brief   RemoTI Audio Subsystem, decoding function. decode encoded audioframe to PCM samples.

+ *

+ * input parameters

+ *

+ * @param   option:    		decoding option. can be pure decoding, or packet lot concealment algorithm:

+ * 							RAS_PACKET_LOST(0)

+ * 							RAS_DECODE(1)

+ * @param   input: 			address of the buffer to decode, this buffer must include the 3 bytes header..

+ *

+ * @param   inputLenght:  	length of the buffer to decode, excluding the 3 bytes header.

+ * 							cannot be greater than 128 (MAX_INPUT_BUF_SIZE);

+ *

+ * output parameters

+ *

+ * @param   output:     	buffer where the decoded PCM will be written. This buffer must be allocated by the caller.

+ * 							it must have a length of 4 times the inputLength variable

+ *

+ * @param   outputLenght:  	length of the decoded buffer.

+ * 							max possible value 512 (4*MAX_INPUT_BUF_SIZE);

+ *

+ *

+ * @return      .

+ * status.	0				SUCCESS

+ * 			-1				ERROR: INVALID PARAMETER

+ *

+ */

+extern uint8 RAS_Decode( uint8 option, uint8* input, uint16 inputLenght, int16* output,uint16 *outputLenght );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif // RSA_LIB_H

diff --git a/gfiber-tools/RAS_lib_ubuntu_x64.a b/gfiber-tools/RAS_lib_ubuntu_x64.a
new file mode 100644
index 0000000..e07b0b7
--- /dev/null
+++ b/gfiber-tools/RAS_lib_ubuntu_x64.a
Binary files differ
diff --git a/gfiber-tools/my_audio.c b/gfiber-tools/my_audio.c
new file mode 100644
index 0000000..0b157d0
--- /dev/null
+++ b/gfiber-tools/my_audio.c
@@ -0,0 +1,165 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "RAS_lib.h"
+
+#define RAS_CMD_MASK 0x07
+#define RAS_START_CMD 0x04
+#define RAS_DATA_TIC1_CMD 0x01
+#define RAS_STOP_CMD 0x02
+#define RAS_DATA_RAW_CMD 0x03
+
+#define FRAME_TYPE(data) (data[3] & RAS_CMD_MASK)
+
+#define PDU_LENGTH 20 + 20 + 20 + 20
+
+// read_with_length reads a byte from the provided fd, then reads that many
+// bytes into buf, unless more bytes are to be read than size.  The number of
+// bytes actually read is returned.  On error, a value less than 0 is returned.
+int read_with_length(int fd, char *buf, int size) {
+  char to_read;
+
+  int len = read(fd, &to_read, 1);
+  if (len != 1) {
+    printf("read_with_length: read %d bytes, expecting 1\n", len);
+    return 0;
+  }
+
+  if (size < to_read) {
+    printf(
+        "read_with_length: file wants to read in %d bytes, but there is only "
+        "space for %d\n",
+        to_read, size);
+    // This puts the file in a bad state (the next byte is no longer a length
+    // byte), but good enough for now.
+    return -1;
+  }
+
+  len = read(fd, buf, to_read);
+  if (len < to_read) {
+    printf("read_with_length: got %d bytes, but wanted %d bytes\n", len, to_read);
+    return -1;
+  }
+  return len;
+}
+
+int parse_pdu(char *pdu, int len) {
+  if (len < 4) {
+    return 0;
+  }
+
+  int sequence = (pdu[3] >> 3) & 0x1f;
+  printf("pdu received: sequence %d\n", sequence);
+
+  switch(FRAME_TYPE(pdu)) {
+    case RAS_START_CMD:
+      printf(" audio start\n");
+      break;
+    case RAS_DATA_TIC1_CMD:
+      printf(" actual audio frame\n");
+      break;
+    case RAS_STOP_CMD:
+      printf(" audio stop\n");
+      break;
+    default:
+      printf(" unhandled pdu frame_type=%d\n", FRAME_TYPE(pdu));
+      break;
+  }
+
+   return 1;
+}
+
+struct pdu_accumulator {
+  int seen_first_packet;
+  int cur_idx;
+  char pdu[PDU_LENGTH];
+};
+
+void reset_pdu_accumulator(struct pdu_accumulator *a) {
+  a->seen_first_packet = 0;
+  a->cur_idx = 0;
+  memset(&(a->pdu), 0, PDU_LENGTH);
+}
+
+
+// accumulate_pdu accepts one 23 byte packet from the device, and returns true
+// if a complete PDU has been assembled.
+int accumulate_pdu(struct pdu_accumulator *a, char data[23]) {
+  // printf("seen_first=%d cur_idx=%d\n", a->seen_first_packet, a->cur_idx);
+
+  if(!a->seen_first_packet) {
+    if(FRAME_TYPE(data) == RAS_DATA_TIC1_CMD) {
+      a->seen_first_packet = 1;
+      a->cur_idx++;
+      memcpy(a->pdu, data, 23);
+    } else {
+      printf(" ignoring unexpected packet (type %d)\n", FRAME_TYPE(data));
+    }
+    return 0;
+  }
+
+  if(a->seen_first_packet) {
+    // if(FRAME_TYPE(data) != RAS_DATA_RAW_CMD) {
+    //   printf("expecting raw data, but got frame type %d\n", FRAME_TYPE(data));
+    //   reset_pdu_accumulator(a);
+    //   return 0;
+    // }
+
+    // copy everything but the first 3 bytes into the result packet 0, read
+    // above, is 23 bytes.  the next 3 are 20 bytes (with the first 3 bytes
+    // ignored).  those 4 packets make a complete PDU.
+    if(a->cur_idx > 0 && a->cur_idx < 4) {
+      memcpy(&(a->pdu[a->cur_idx*20]), &data[3], 20);
+      a->cur_idx++;
+    } else {
+      printf(" cur_idx %d out of range\n", a->cur_idx);
+    }
+  }
+
+  return a->cur_idx > 3;
+}
+
+
+int main(int argc, char **argv) {
+  // TI ignores the error code from RAS_Init.  I will too, I guess.
+  RAS_Init(1);
+
+  int input = open("out", O_RDONLY);
+  if (input < 0) {
+    perror("open ./out");
+    return 1;
+  }
+
+  struct pdu_accumulator a;
+  reset_pdu_accumulator(&a);
+  char data[64];
+
+chunk:
+  while (1) {
+    int read = read_with_length(input, data, sizeof(data));
+    if (read < 1) {
+      return 1;
+    }
+    // printf("read %d bytes\n", read);
+
+    switch (read) {
+      case 4:
+        parse_pdu(data, read);
+        reset_pdu_accumulator(&a);
+        break;
+
+      case 23:
+        if(accumulate_pdu(&a, data)) {
+          parse_pdu(a.pdu, PDU_LENGTH);
+          reset_pdu_accumulator(&a);
+        }
+        break;
+    }
+  }
+
+  return 0;
+}
diff --git a/gfiber-tools/playback.c b/gfiber-tools/playback.c
new file mode 100644
index 0000000..7472d0e
--- /dev/null
+++ b/gfiber-tools/playback.c
@@ -0,0 +1,41 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  int outfd, infd, len, wrote;
+  char data[131072];
+
+  infd = open("out", O_RDONLY);
+  if (infd < 0) {
+    perror("open ./out");
+    return 1;
+  }
+
+  read(infd, &data, 131072);
+
+  int offset = 0;
+  while (1) {
+    outfd = open("/tmp/Fifo_bdt_tiaudio", O_WRONLY);
+    if (outfd < 0) {
+      perror("open /tmp/Fifo_bdt_tiaudio");
+      return 1;
+    }
+
+    len = data[offset];
+    printf("%d data bytes to write\n", len);
+    if (len == 0) {
+      return 0;
+    }
+
+    wrote = write(outfd, &data[offset], len + 1);
+    offset += len + 1;
+    if (wrote != len + 1) {
+      printf("only wrote %d/%d bytes.  skipping.\n", wrote, len + 1);
+    }
+
+    close(outfd);
+    usleep(1000);
+  }
+}
diff --git a/gfiber-tools/raw_read.c b/gfiber-tools/raw_read.c
new file mode 100644
index 0000000..274a817
--- /dev/null
+++ b/gfiber-tools/raw_read.c
@@ -0,0 +1,35 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  int infd;
+  char buf[256];
+  int len, wlen;
+
+  int outfd = open("out", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+  if (outfd < 0) {
+    perror("open out");
+    return 1;
+  }
+
+  while (1) {
+    infd = open("/tmp/Fifo_bdt_tiaudio", O_RDONLY);
+    if (infd == -1) {
+      perror("open /tmp/Fifo_bdt_tiaudio");
+      return 1;
+    }
+
+    len = read(infd, buf, 256);
+    if (len != 0) {
+      printf("read %d bytes\n", len);
+      wlen = write(outfd, &buf, len);
+      if (len != wlen) {
+        printf("write error, wrote %d/%d\n", wlen, len);
+      }
+    }
+    close(infd);
+  }
+  return 0;
+}
diff --git a/gfiber-tools/ti_audio.c b/gfiber-tools/ti_audio.c
new file mode 100644
index 0000000..952e90f
--- /dev/null
+++ b/gfiber-tools/ti_audio.c
@@ -0,0 +1,560 @@
+/**************************************************************************************************
+  Filename:       ti_audio.c
+
+  Description:    audio over BLe, audio decoding app
+
+
+  Copyright 2013 Texas Instruments Incorporated. All rights reserved.
+
+  IMPORTANT: Your use of this Software is limited to those specific rights
+  granted under the terms of a software license agreement between the user
+  who downloaded the software, his/her employer (which must be your employer)
+  and Texas Instruments Incorporated (the "License").  You may not use this
+  Software unless you agree to abide by the terms of the License. The License
+  limits your use, and you acknowledge, that the Software may not be modified,
+  copied or distributed unless embedded on a Texas Instruments microcontroller
+  or used solely and exclusively in conjunction with a Texas Instruments radio
+  frequency transceiver, which is integrated into your product.  Other than for
+  the foregoing purpose, you may not use, reproduce, copy, prepare derivative
+  works of, modify, distribute, perform, display or sell this Software and/or
+  its documentation for any purpose.
+
+  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
+  PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+  INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
+  NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
+  TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
+  NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
+  LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
+  INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
+  OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
+  OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
+  (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
+
+  Should you have any questions regarding your right to use this Software,
+  contact Texas Instruments Incorporated at www.TI.com.
+**************************************************************************************************/
+#include <fcntl.h>
+#include <getopt.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "RAS_lib.h"
+
+#define FIFO_BTD2AUDIO_FILE "/tmp/Fifo_bdt_tiaudio"
+
+#define RAS_CMD_MASK 0x07
+#define RAS_START_CMD 0x04
+#define RAS_DATA_TIC1_CMD 0x01
+#define RAS_STOP_CMD 0x02
+#define RAS_DATA_RAW_CMD 0x03
+
+#define TRUE 1
+#define FALSE 0
+
+int fp;
+
+static pthread_mutex_t audio_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int frame_type;
+int SeqNum, PrevSeqNum;
+static float throughput, throughput_min = 10000000, throughput_max = 0,
+                         throughput_ave = 0, throughput_raw_ave = 0;
+static int cumulatedBytes = 0;
+static int totalcumulatedBytes = 0;
+static int totalcumulatedRawBytes = 0;
+struct timeval prevTimeThrougput, prevTimeStarting, curTime, prevPacket;
+long int elapsedTimeSinceLastPacket = 1;
+char ras_pec_mode;
+char previousFrameExist = 0;
+unsigned char audioFrame[200];
+unsigned char audio_data_len;
+unsigned char audioFrameIndex = 0;
+FILE *fout_wav;
+FILE *fout_tic1;
+char outFile_wav[1024];
+char outFile_tic1[1024];
+char fileListIndex = 0;
+char NewFilename[1024] = "";
+char NewOutputFilename[1024] = "";
+char outFile[1024];
+unsigned char Data_len;
+int file_open = FALSE;
+int streamStarted = TRUE;
+int nbFrameLost;
+int nbFrameReceived;
+
+static void audioRenameOutputFile(void) {
+  strcpy(NewFilename, "");
+  strcpy(NewOutputFilename, "");
+  strcat(NewOutputFilename, "gattToolAudio");
+
+  {
+    {
+      char temp[8];
+      fileListIndex++;
+      strncat(NewOutputFilename, outFile, strlen(outFile));
+      strcat(NewOutputFilename, "_");
+      sprintf(temp, "%d", fileListIndex);
+      strcat(NewOutputFilename, temp);
+    }
+  }
+
+  // Add the new suffix.
+  strcpy(outFile_wav, NewOutputFilename);
+  strcpy(outFile_tic1, NewOutputFilename);
+  strcat(outFile_wav, ".wav");
+  strcat(outFile_tic1, ".tic1");
+
+  // Open the file
+  {
+    fout_wav = fopen(outFile_wav, "w");
+    if (fout_wav != NULL) {
+      printf("===> Wav File Created %s  <=== \n", outFile_wav);
+
+    } else {
+      perror("fopen3:");
+      exit(-1);
+    }
+    fout_tic1 = fopen(outFile_tic1, "w");
+    if (fout_tic1 != NULL) {
+      printf("===> TIC1 File Created %s  <=== \n", outFile_tic1);
+    } else {
+      perror("fopen4:");
+      exit(-1);
+    }
+    file_open = TRUE;
+  }
+}
+
+static void audioAddWaveHeader(FILE *fout_wav) {
+  // Initialize directly subchunksize1
+  unsigned char Header[100] = {0x52, 0x49, 0x46, 0x46, 0xFF, 0xFF,
+                               0xFF, 0xFF, 0x57, 0x41, 0x56, 0x45};
+
+  // subchunksize2
+  Header[12] = 0x66;
+  Header[13] = 0x6d;
+  Header[14] = 0x74;
+  Header[15] = 0x20;
+
+  Header[16] = 16;
+  Header[17] = 0;
+  Header[18] = 0;
+  Header[19] = 0;
+
+  Header[20] = 1;
+  Header[21] = 0;
+
+  Header[22] = 1;
+  Header[23] = 0;
+
+  Header[24] = 0x80;
+  Header[25] = 0x3E;
+  Header[26] = 0;
+  Header[27] = 0;
+
+  Header[28] = 0x00;
+  Header[29] = 0x7D;
+  Header[30] = 0;
+  Header[31] = 0;
+
+  Header[32] = 2;
+  Header[33] = 0;
+
+  Header[34] = 16;
+  Header[35] = 0;
+
+  Header[36] = 0x64;
+  Header[37] = 0x61;
+  Header[38] = 0x74;
+  Header[39] = 0x61;
+
+  Header[40] = 0xFF;
+  Header[41] = 0xFF;
+  Header[42] = 0xFF;
+  Header[43] = 0xFF;
+
+  fwrite(Header, sizeof(char), 44, fout_wav);
+  printf("===> Add Wav Header <=== \n");
+}
+
+long int audioElapsedTime(struct timeval *timeStart, struct timeval *timeEnd) {
+  long int diffPrev;
+  long int decrementValue;
+  int t = 0;
+
+  if (timeStart->tv_usec >= timeEnd->tv_usec) {
+    diffPrev = timeStart->tv_usec - timeEnd->tv_usec;
+    t = 0;
+  } else {
+    diffPrev = (timeStart->tv_usec + 1000000) - timeEnd->tv_usec;
+    t = 1;
+  }
+
+  decrementValue =
+      (diffPrev + 1000000 * (timeStart->tv_sec - timeEnd->tv_sec - t)) /
+      1000;  // Res in ms
+  return decrementValue;
+}
+
+void audioResetStream(void) {
+  gettimeofday(&prevTimeThrougput, NULL);
+  gettimeofday(&prevTimeStarting, NULL);
+
+  totalcumulatedBytes = 0;
+  totalcumulatedRawBytes = 0;
+  cumulatedBytes = 0;
+  throughput = 0;
+  throughput_min = 10000000;
+  throughput_max = 0;
+  throughput_ave = 0;
+  throughput_raw_ave = 0;
+  PrevSeqNum = 0;
+  ras_pec_mode = 1;
+  streamStarted = FALSE;
+  nbFrameLost = 0;
+  nbFrameReceived = 0;
+
+  if (RAS_Init(ras_pec_mode)) {
+    // printf("fail to initialize remoTI audio subsystem");
+    // exit(-1);
+  }
+  previousFrameExist = 0;
+  audioFrameIndex = 0;
+
+  elapsedTimeSinceLastPacket = audioElapsedTime(&curTime, &prevPacket);
+
+  if (file_open && elapsedTimeSinceLastPacket > 700) {
+    // Equivalent to dead link timer
+    // Close current file and reopen a new one.
+    // Stop Frame
+    fflush(fout_wav);
+    fclose(fout_wav);
+    fout_wav = NULL;
+    fflush(fout_tic1);
+    fclose(fout_tic1);
+    fout_tic1 = NULL;
+
+    // Need to add File size in the header of the wav file
+    {
+      int filesize;
+      unsigned char file[4];
+      fout_wav = fopen(outFile_wav, "r+b");
+      if (fout_wav == NULL) {
+        perror("fopen6:");
+        exit(-1);
+      }
+
+      fseek(fout_wav, 0L, SEEK_END);
+      filesize = ftell(fout_wav);
+
+      file[0] = (unsigned char)(((filesize - 44) & 0xFF));
+      file[1] = (unsigned char)(((filesize - 44) & 0xFF00) >> 8);
+      file[2] = (unsigned char)(((filesize - 44) & 0xFF0000) >> 16);
+      file[3] = (unsigned char)(((filesize - 44) & 0xFF000000) >> 24);
+      fseek(fout_wav, 40, SEEK_SET);
+      fwrite(file, 1, 4, fout_wav);
+      fclose(fout_wav);
+      fout_wav = NULL;
+    }
+    file_open = FALSE;
+
+    printf("===> AUDIO STOP BEFORE START <=== \n");
+  }
+
+  if (!file_open) {
+    audioRenameOutputFile();
+    // Add .Wav header to .wave output file
+    if (fout_wav) audioAddWaveHeader(fout_wav);
+  }
+}
+
+static void audio_ParseData(unsigned char *pdu, unsigned short len) {
+  long int decrementValue, elapsed_time;
+  int i;
+  frame_type = pdu[3] & 0x7;
+  SeqNum = (pdu[3] >> 3) & 0x1F;
+  // s = g_string_new(NULL);
+
+  Data_len =
+      (len -
+       4);  // This is audio data length only (audio frame header+ audio data)
+  // printf("FT = 0x%02x ,SeqNum: %d, len: %d\n", frame_type, SeqNum, len);
+
+  cumulatedBytes += Data_len;
+  totalcumulatedBytes += Data_len;
+  totalcumulatedRawBytes += Data_len + 3 + 4 + 1;
+
+  gettimeofday(&curTime, NULL);
+  decrementValue = audioElapsedTime(&curTime, &prevTimeThrougput);
+  elapsed_time = audioElapsedTime(&curTime, &prevTimeStarting);
+
+  // check if 1s has elapse since last packet.
+  if (decrementValue > 1000) {
+    // Calculate and Display Throughput
+    throughput =
+        (float)(8 * (((float)cumulatedBytes) / ((float)decrementValue)));
+    (throughput_min > throughput) ? throughput_min = throughput
+                                  : throughput_min;
+    (throughput_max < throughput) ? throughput_max = throughput
+                                  : throughput_max;
+    gettimeofday(&prevTimeThrougput, NULL);
+  }
+
+  if (elapsed_time > 500)  // Not meaningful before
+  {
+    throughput_ave =
+        (float)(8 * ((float)totalcumulatedBytes) / ((float)elapsed_time));
+    throughput_raw_ave =
+        (float)(8 * ((float)totalcumulatedRawBytes) / ((float)elapsed_time));
+  }
+
+  if (decrementValue > 1000) {
+    cumulatedBytes = 0;
+    printf(
+        "ElapsedTime(ms): %ld, throughput(kbps): %2.2f (%2.2f/%2.2f)  "
+        "Ave:(%2.2f) Raw Ave: (%2.2f), AudioPER:%2.2f%%, ( %d lost over %d "
+        "sent)  \n",
+        elapsed_time, throughput, throughput_min, throughput_max,
+        throughput_ave, throughput_raw_ave,
+        (double)(100 * (double)nbFrameLost /
+                 (double)(nbFrameLost + nbFrameReceived)),
+        nbFrameLost, nbFrameReceived + nbFrameLost);
+  }
+
+  // Throughput estimation
+  if (frame_type == RAS_START_CMD) {
+    printf("===> AUDIO START  <=== \n");
+    audioResetStream();
+    streamStarted = TRUE;
+  } else if (frame_type == RAS_DATA_TIC1_CMD) {
+    if (!streamStarted) {
+      audioResetStream();
+      streamStarted = TRUE;
+    }
+    nbFrameReceived++;
+    gettimeofday(&prevPacket, NULL);
+    if (PrevSeqNum + 1 != SeqNum) {
+      if (SeqNum < (PrevSeqNum + 1)) {
+        nbFrameLost += 32 + SeqNum - (PrevSeqNum + 1);
+      } else
+        nbFrameLost += SeqNum - (PrevSeqNum + 1);
+      printf("FRAME LOST !!!!(%d != %d) (%d nbFrameLost for %d sent\n",
+             PrevSeqNum + 1, SeqNum, nbFrameLost,
+             nbFrameLost + nbFrameReceived);
+    }
+
+    if (SeqNum == 31)
+      PrevSeqNum = -1;
+    else
+      PrevSeqNum = SeqNum;
+
+    // Decode Frame if any exist.
+    if (previousFrameExist) {
+      short temp[1024];
+      unsigned short decLength;
+
+      // printf("decode Frame %d\n", PrevSeqNum  );
+      RAS_Decode(RAS_DECODE_TI_TYPE1, audioFrame, audio_data_len, temp,
+                 &decLength);
+      if (fout_wav != NULL) {
+        /*Write the decoded audio to file*/
+        fwrite(temp, sizeof(short), decLength / 2, fout_wav);
+      }
+
+      if (fout_tic1 != NULL) {
+        int8 temp2[512];
+        temp2[0] = audio_data_len;
+        memcpy(&temp2[1], audioFrame, audio_data_len);
+
+        /*Write the decoded audio to file*/
+        fwrite(temp2, sizeof(char), audio_data_len + 1, fout_tic1);
+      }
+    }
+
+    previousFrameExist = 1;
+
+    // Store Data in audio frame:
+    audioFrameIndex = 0;
+    audio_data_len = Data_len;  // Remove audio frame Header
+    for (i = 0; i < Data_len; i++) audioFrame[audioFrameIndex++] = pdu[i + 4];
+
+  } else if (frame_type == RAS_STOP_CMD) {
+    printf("===> AUDIO STOP  <=== \n");
+    // Stop Frame
+    fflush(fout_wav);
+    fclose(fout_wav);
+    fout_wav = NULL;
+    fflush(fout_tic1);
+    fclose(fout_tic1);
+    previousFrameExist = 0;
+    fout_tic1 = NULL;
+
+    // Need to add File size in the header of the wav file
+    {
+      int filesize;
+      unsigned char file[4];
+      fout_wav = fopen(outFile_wav, "r+b");
+      if (fout_wav != NULL) {
+        printf("===> Wav File open for length update: %s  <=== \n",
+               outFile_wav);
+      } else {
+        perror("fopen5:");
+        exit(-1);
+      }
+      fseek(fout_wav, 0L, SEEK_END);
+      filesize = ftell(fout_wav);
+
+      file[0] = (unsigned char)(((filesize - 44) & 0xFF));
+      file[1] = (unsigned char)(((filesize - 44) & 0xFF00) >> 8);
+      file[2] = (unsigned char)(((filesize - 44) & 0xFF0000) >> 16);
+      file[3] = (unsigned char)(((filesize - 44) & 0xFF000000) >> 24);
+      fseek(fout_wav, 40, SEEK_SET);
+      fwrite(file, 1, 4, fout_wav);
+      fclose(fout_wav);
+      fout_wav = NULL;
+    }
+    file_open = FALSE;
+  }
+}
+
+int main(int argc, char **argv) {
+  int attframecnt = 0;
+  int bytes_read = 0;
+  int num_bytes = 0;
+  int total_bytes = 0;
+  int read_state = 0;
+  unsigned char readbuf[256];
+  unsigned char dummybuf[256];
+
+  while (1) {
+    pthread_mutex_lock(&audio_mutex);
+    {
+      // printf("Open reading pipe ...\n");
+      fp = open(FIFO_BTD2AUDIO_FILE, O_RDONLY);
+      if (fp == -1) {
+        printf("can't open the pipe\n");
+        exit(-1);
+      }
+
+      // Read a single byte to know the length of the data
+      bytes_read = read(fp, &num_bytes, 1);
+      printf("%d bytes of Data (bytes to read further=%d): \n", bytes_read,
+             num_bytes);
+      if ((bytes_read) && (num_bytes == 4)) {
+        printf("Reading %d bytes of Audio Frame\n", num_bytes);
+        bytes_read = read(fp, &readbuf[0], num_bytes);
+        total_bytes += bytes_read;
+
+        printf("Submitting Audio Frame. Size=%d\n", total_bytes);
+
+        // Call Audio protocol Handler:
+        audio_ParseData(&readbuf[0], total_bytes);
+        total_bytes = 0;
+
+      } else if ((bytes_read) && (num_bytes == 23)) {
+        if (read_state == 0) {
+          int rasFrame = 0;
+          bytes_read = read(fp, &readbuf[total_bytes], num_bytes);
+          total_bytes += bytes_read;
+          printf(
+              "Received %d bytes of Data (total_bytes=%d), retrieve data: \n",
+              bytes_read, total_bytes);
+
+          rasFrame = readbuf[3] & 0x7;
+          if (rasFrame == 0x01) {
+            // Reading Complete Audio Frame
+            read_state = 1;
+            attframecnt = 0;
+          }
+        }
+
+        if (read_state == 1) {
+          /*
+                                                  //Read a single byte to know
+             the length of the data
+                                                  bytes_read = read(fp,
+             &num_bytes, 1);
+                                                  printf("%d bytes of Data
+             (bytes to read further=%d): \n", bytes_read, num_bytes);
+                  //					printf("Bytes to read =
+             %d\n",
+             num_bytes);
+                                                  if( (bytes_read) && (num_bytes
+             == 23))
+                                                  {
+                  */
+          // Read the ATT Header data(3 Bytes) to Dummy file
+          bytes_read = read(fp, &dummybuf[0], 3);
+          // Read Actual data to readbuf
+          bytes_read = read(fp, &readbuf[total_bytes], (num_bytes - 3));
+          total_bytes += bytes_read;
+          printf("Received %d bytes of Data (total_bytes=%d): \n", bytes_read,
+                 total_bytes);
+          attframecnt += 1;
+          /*						}
+                                          else
+                                          {
+                                                  if(bytes_read)
+                                                  {
+                                                          //Read the ATT frame
+             to Dummy buffer
+                                                          printf("Error while
+             reading Audio ATT Frame. Only %d bytes\n", num_bytes);
+                                                          bytes_read = read(fp,
+             &dummybuf[0], num_bytes);
+                                                          printf("Audio noti:
+             Len: %d, Data: (0) 0x%x, Data: (1) 0x%x, Data: (2) 0x%x, Data: (3)
+             0x%x, (4) 0x%x, (5) 0x%x, (6) 0x%x, (7) 0x%x, (8) 0x%x, (9) 0x%x,
+             (10) 0x%x, (11) 0x%x, (12) 0x%x, (19) 0x%x, (20) 0x%x, (21) 0x%x,
+             (22) 0x%x ", num_bytes, dummybuf[0],  dummybuf[1], dummybuf[2],
+             dummybuf[3], dummybuf[4], dummybuf[5], dummybuf[6], dummybuf[7],
+             dummybuf[8], dummybuf[9], dummybuf[10], dummybuf[11], dummybuf[12],
+             dummybuf[num_bytes-4], dummybuf[num_bytes-3],
+             dummybuf[num_bytes-2], dummybuf[num_bytes-1]);
+
+                                                  }
+                                          }
+  */
+        }
+
+        if (attframecnt > 4) {
+          printf("Submitting Audio Frame. Size=%d\n", total_bytes);
+          // Call Audio protocol Handler:
+          audio_ParseData(&readbuf[0], total_bytes);
+          read_state = 0;
+          total_bytes = 0;
+        }
+
+      } else {
+        if (bytes_read) {
+          // Read the ATT frame to Dummy buffer
+          bytes_read = read(fp, &dummybuf[0], num_bytes);
+          printf("Ignoring ATT Frame\n");
+        } else {
+          printf("End of Pipe Reached. Closing Pipe\n");
+        }
+      }
+
+      // Send Data Back to the Coordinator or End Device
+      // printf("\n");
+
+      bytes_read = 0;
+      num_bytes = 0;
+
+      printf("Close reading pipe...\n");
+      close(fp);
+    }
+    pthread_mutex_unlock(&audio_mutex);
+
+    //		msleep(500);
+  }
+
+  printf("Exiting App...\n");
+}
diff --git a/gfiber-tools/ti_codec b/gfiber-tools/ti_codec
new file mode 100755
index 0000000..c111342
--- /dev/null
+++ b/gfiber-tools/ti_codec
Binary files differ