FM : Add new hci commands and compile changes

Added HAL changes for hci commands like peek, poke, get/set of
SINR sample/threshold.Compile time changes for adding correct
includes based on new bluetooth stack structure, code cleanup
and indendation.

Change-Id: I5e48f0c0dc6165d61335c6d8cc269891e26dd548
diff --git a/fm_hci/Android.mk b/fm_hci/Android.mk
index 1c4b949..2546902 100644
--- a/fm_hci/Android.mk
+++ b/fm_hci/Android.mk
@@ -11,7 +11,7 @@
   bdroid_CFLAGS += -DHAS_NO_BDROID_BUILDCFG
 endif
 
-BDROID_DIR:= external/bluetooth/bluedroid
+BDROID_DIR:= system/bt
 
 LOCAL_CFLAGS += $(bdroid_CFLAGS)
 
@@ -28,6 +28,8 @@
 
 LOCAL_C_INCLUDES += \
         $(BDROID_DIR)/hci/include \
+        $(BDROID_DIR)/stack/include \
+        $(BDROID_DIR)/osi/include \
         $(LOCAL_PATH)/../helium
 
 LOCAL_MODULE := libfm-hci
diff --git a/fm_hci/fm_hci.c b/fm_hci/fm_hci.c
index 1394565..e0294ee 100644
--- a/fm_hci/fm_hci.c
+++ b/fm_hci/fm_hci.c
@@ -34,18 +34,24 @@
 
 #include "bt_hci_bdroid.h"
 #include "bt_vendor_lib.h"
-#include "hci.h"
 #include "userial.h"
-#include "utils.h"
 #include "fm_hci.h"
 #include "wcnss_hci.h"
 #include <dlfcn.h>
 #include <sys/eventfd.h>
 #include <errno.h>
+#include <string.h>
 
 int fm_fd;
 fm_hal_cb *hal_cb;
 
+// The set of events one can send to the userial read thread.
+// Note that the values must be >= 0x8000000000000000 to guarantee delivery
+// of the message (see eventfd(2) for details on blocking behaviour).
+enum {
+    USERIAL_RX_EXIT     = 0x8000000000000000ULL
+};
+
 void event_notification(uint16_t event)
 {
     pthread_mutex_lock(&fmHCIControlBlock.event_lock);
@@ -84,90 +90,90 @@
 /* De-queues the FM CMD from the TX_Q */
 void dequeue_fm_tx_cmd()
 {
-	TX_Q *new_first, *new_last;
-	static int cmd_count = 0;
-	static uint8_t credits = 0;
-	uint8_t i;
-	uint8_t temp_1 = 0x11;
+    TX_Q *new_first, *new_last;
+    static int cmd_count = 0;
+    static uint8_t credits = 0;
+    uint8_t i;
+    uint8_t temp_1 = 0x11;
 
-	if (cmd_count >= MAX_FM_CMD_CNT) {
-		ALOGI("\n\n\t\tReached Max. CMD COUNT!!\n\n");
-		lib_running = 0;
-		return;
-	}
+    if (cmd_count >= MAX_FM_CMD_CNT) {
+        ALOGI("\n\n\t\tReached Max. CMD COUNT!!\n\n");
+        lib_running = 0;
+        return;
+    }
 
-	/*
-	 * Save the 'first' pointer and make it NULL.
-	 * This is to allow the FM-HAL to enqueue more CMDs to the TX_Q
-	 * without having to contend for the 'tx_q_lock' with the FM-HCI thread.
-	 * Once the pointer to the 'first' element in the TX_Q is available,
-	 * send all the commands in the queue to WCNSS FILTER based on the
-	 * command credits provided by the Controller. If command credits are
-	 * not available, then wait for the same.
-	 */
-	pthread_mutex_lock(&fmHCIControlBlock.tx_q_lock);
-	if (!fmHCIControlBlock.first) {
-		ALOGI("No FM CMD available in the Q\n");
-		pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
-		return;
-	}
-	else {
-		new_first = fmHCIControlBlock.first;
-		new_last  = fmHCIControlBlock.last;
-		fmHCIControlBlock.first = fmHCIControlBlock.last = NULL;
-	}
-	pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
+    /*
+     * Save the 'first' pointer and make it NULL.
+     * This is to allow the FM-HAL to enqueue more CMDs to the TX_Q
+     * without having to contend for the 'tx_q_lock' with the FM-HCI thread.
+     * Once the pointer to the 'first' element in the TX_Q is available,
+     * send all the commands in the queue to WCNSS FILTER based on the
+     * command credits provided by the Controller. If command credits are
+     * not available, then wait for the same.
+     */
+    pthread_mutex_lock(&fmHCIControlBlock.tx_q_lock);
+    if (!fmHCIControlBlock.first) {
+        ALOGI("No FM CMD available in the Q\n");
+        pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
+        return;
+    }
+    else {
+        new_first = fmHCIControlBlock.first;
+        new_last  = fmHCIControlBlock.last;
+        fmHCIControlBlock.first = fmHCIControlBlock.last = NULL;
+    }
+    pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
 
-	//credits = command_credits;
+    //credits = command_credits;
 
-	TX_Q *temp = new_first;
-	while(temp != NULL) {
+    TX_Q *temp = new_first;
+    while(temp != NULL) {
 
 wait_for_cmd_credits:
-		pthread_mutex_lock(&fmHCIControlBlock.credit_lock);
-		while (command_credits == 0) {
-			ALOGI("\n\n\t\tWaiting for COMMAND CREDITS from CONTROLLER\n\n");
-			pthread_cond_wait(&fmHCIControlBlock.cmd_credits_cond, &fmHCIControlBlock.credit_lock);
-		}
-		pthread_mutex_unlock(&fmHCIControlBlock.credit_lock);
+        pthread_mutex_lock(&fmHCIControlBlock.credit_lock);
+        while (command_credits == 0) {
+              ALOGI("\n\n\t\tWaiting for COMMAND CREDITS from CONTROLLER\n\n");
+              pthread_cond_wait(&fmHCIControlBlock.cmd_credits_cond, &fmHCIControlBlock.credit_lock);
+        }
+        pthread_mutex_unlock(&fmHCIControlBlock.credit_lock);
 
-		/* Check if we really got the command credits */
-		//REVISIT this area
-		//if (credits) {
-		if (command_credits) {
-			ALOGI("%s: Sending the FM-CMD(prot_byte: 0x%x): 0x%x dequeued from TX_Q\n", __func__, temp->hdr->protocol_byte, temp->hdr->opcode);
+        /* Check if we really got the command credits */
+        //REVISIT this area
+        //if (credits) {
+        if (command_credits) {
+            ALOGI("%s: Sending the FM-CMD(prot_byte: 0x%x): 0x%x dequeued from TX_Q\n", __func__, temp->hdr->protocol_byte, temp->hdr->opcode);
 
-			if (temp->hdr->plen) {
-				ALOGI("%s: CMD-PARAMS:", __func__);
-				for (i = 0; i < temp->hdr->plen; i++)
-					ALOGI(" <0x%x> ", temp->hdr->cmd_params[i]);
-			} else
-				ALOGE("%s: NO CMD-PARAMS available for this command", __func__);
+            if (temp->hdr->plen) {
+                ALOGI("%s: CMD-PARAMS:", __func__);
+                for (i = 0; i < temp->hdr->plen; i++)
+                    ALOGI(" <0x%x> ", temp->hdr->cmd_params[i]);
+            } else
+                ALOGE("%s: NO CMD-PARAMS available for this command", __func__);
 
-			ALOGE("%s: Sizeof FM_HDR: %d", __func__, (int)sizeof(temp->hdr));
-			/* Use socket 'fd' to send the command down to WCNSS Filter */
-			write(fm_fd, (uint8_t *)temp->hdr, (sizeof(FM_HDR) + temp->hdr->plen));
-			//write(fd, &temp_1, 1);
+            ALOGE("%s: Sizeof FM_HDR: %d", __func__, (int)sizeof(temp->hdr));
+            /* Use socket 'fd' to send the command down to WCNSS Filter */
+            write(fm_fd, (uint8_t *)temp->hdr, (sizeof(FM_HDR) + temp->hdr->plen));
+            //write(fd, &temp_1, 1);
 
-			/* Decrement cmd credits by '1' after sending the cmd*/
-			command_credits--;
+            /* Decrement cmd credits by '1' after sending the cmd*/
+            command_credits--;
 
-			/* TODO:
-			 * Initialize 'cmd_cnt' to MAX_FM_CMD(?). Should we have any limit on the
-			 * number of outstanding commands in the TX-Q ??
-			 */
-			cmd_count--;
+            /* TODO:
+             * Initialize 'cmd_cnt' to MAX_FM_CMD(?). Should we have any limit on the
+             * number of outstanding commands in the TX-Q ??
+             */
+            cmd_count--;
 
-			/* Fetch the next cmd to be sent */
-			temp = temp->next;
-		} else {
-			if (!lib_running)
-				break;
+            /* Fetch the next cmd to be sent */
+            temp = temp->next;
+        } else {
+            if (!lib_running)
+                break;
 
-			ALOGI("\n\n\t\tFalse wakeup: Yet to get COMMAND CREDITS from CONTROLLER\n\n");
-			goto wait_for_cmd_credits;
-		}
-	}
+            ALOGI("\n\n\t\tFalse wakeup: Yet to get COMMAND CREDITS from CONTROLLER\n\n");
+            goto wait_for_cmd_credits;
+        }
+    }
 }
 
 
@@ -218,30 +224,29 @@
         FD_SET(event_fd, &readFds);
         int fd_max = (event_fd > fd ? event_fd : fd);
 
-        ALOGE("%s: Waiting for events from WCNSS FILTER...\n", __func__);
+        ALOGV("%s: Waiting for events from WCNSS FILTER...\n", __func__);
 
         /* Wait for event/data from WCNSS Filter */
         n = select(fd_max+1, &readFds, NULL, NULL, NULL);
         if (n > 0)
         {
             /* Check if event is available or not */
-#if 1
             if (FD_ISSET(fd, &readFds)) {
                 ret = read(fd, (uint8_t *)pbuf, (size_t)(sizeof(FM_EVT_HDR) + MAX_FM_EVT_PARAMS));
                 if (0 == ret) {
-                    ALOGE("%s: read() returned '0' bytes\n", __func__);
+                    ALOGD("%s: read() returned '0' bytes\n", __func__);
                 }
                 else {
-                    ALOGE("%s: read() returned %d bytes of FM event/data\n", __func__, ret);
+                    ALOGV("%s: read() returned %d bytes of FM event/data\n", __func__, ret);
                     while (ret > 0) {
                         if (pbuf->evt_code == FM_CMD_COMPLETE) {
-                            ALOGE("\n\t%s: Received %d bytes of CC event data from WCNSS FILTER!!!\n\t"
+                            ALOGV("\n\t%s: Received %d bytes of CC event data from WCNSS FILTER!!!\n\t"
                                 "Evt type\t: 0x%x \n\tEvt Code\t: 0x%x \n\tEvt len\t\t: 0x%x \n\topcode\t\t: 0x%x%x \n\tCmd Credits\t: 0x%x \n\tStatus\t\t: 0x%x\n",
                                 __func__, ret, pbuf->protocol_byte, pbuf->evt_code, pbuf->evt_len, pbuf->cmd_params[2], pbuf->cmd_params[1],
                             pbuf->cmd_params[0], pbuf->cmd_params[3]);
                             evt_type = FM_CMD_COMPLETE;
                         } else if (pbuf->evt_code == FM_CMD_STATUS) {
-                            ALOGE("\n\t%s: Received %d bytes of CS event data from WCNSS FILTER!!!\n\t"
+                            ALOGV("\n\t%s: Received %d bytes of CS event data from WCNSS FILTER!!!\n\t"
                                 "Evt type\t: 0x%x \n\tEvt Code\t: 0x%x \n\tEvt len\t\t: 0x%x \n\topcode\t\t: 0x%x%x \n\tCmd Credits\t: 0x%x \n\tStatus\t\t: 0x%x\n",
                                 __func__, ret, pbuf->protocol_byte, pbuf->evt_code, pbuf->evt_len, pbuf->cmd_params[3], pbuf->cmd_params[2],
                             pbuf->cmd_params[1], pbuf->cmd_params[0]);
@@ -251,7 +256,6 @@
                               lib_running =0;
                               // commented till bt vendor include added
                              // fm_vnd_if->ssr_cleanup();
-
                         } else {
                             ALOGI("%s: Not CS/CC Event: Recvd. Event Code: 0x%2x", __func__, pbuf->evt_code);
                             evt_type = -1;
@@ -260,7 +264,7 @@
                         evt_len = pbuf->evt_len;
 
                         /* Notify 'fmHCITask' about availability of event or data */
-                        ALOGE("%s: \nNotifying 'fmHCITask' availability of FM event or data...\n", __func__);
+                        ALOGI("%s: \nNotifying 'fmHCITask' availability of FM event or data...\n", __func__);
                         event_notification(HC_EVENT_RX);
 
                         if (hal_cb && hal_cb->fm_evt_notify != NULL)
@@ -272,11 +276,11 @@
                             /* Provide command credits to allow fmHCITask to send cmds */
                             pthread_mutex_lock(&fmHCIControlBlock.credit_lock);
                             if (evt_type == FM_CMD_COMPLETE) {
-                                ALOGE("\n%s: Command Credit(s): '%d' received as part of CC Event for FM-CMD: 0x%x%x \n", __func__, pbuf->cmd_params[0],
+                                ALOGD("\n%s: Command Credit(s): '%d' received as part of CC Event for FM-CMD: 0x%x%x \n", __func__, pbuf->cmd_params[0],
                                      pbuf->cmd_params[2], pbuf->cmd_params[1]);
                                 command_credits = pbuf->cmd_params[0];
                             } else if (evt_type == FM_CMD_STATUS) {
-                                ALOGE("\n%s: Command Credit(s): '%d' received as part of CS Event for FM-CMD: 0x%x%x \n", __func__, pbuf->cmd_params[1],
+                                ALOGI("\n%s: Command Credit(s): '%d' received as part of CS Event for FM-CMD: 0x%x%x \n", __func__, pbuf->cmd_params[1],
                                     pbuf->cmd_params[3], pbuf->cmd_params[2]);
                                 command_credits = pbuf->cmd_params[1];
                             }
@@ -297,8 +301,7 @@
                 } //end of processing the event
 
             } else
-                ALOGE("%s: No data available, though select returned!!!\n", __func__);
-#endif
+                ALOGV("%s: No data available, though select returned!!!\n", __func__);
         }
         else if (n < 0) {
            ALOGE("%s: select() failed with return value: %d", __func__, ret);
@@ -313,19 +316,19 @@
 
 static void *userial_read_thread(void *arg)
 {
-	int length;
+    int length;
 
-       FM_EVT_HDR *evt_buf = (FM_EVT_HDR *) malloc(sizeof(FM_EVT_HDR) + MAX_FM_EVT_PARAMS);
+    FM_EVT_HDR *evt_buf = (FM_EVT_HDR *) malloc(sizeof(FM_EVT_HDR) + MAX_FM_EVT_PARAMS);
 
-       ALOGE("%s: Wait for events from the WCNSS Filter", __func__);
-       length = read_fm_event(fm_fd, evt_buf, sizeof(FM_EVT_HDR) + MAX_FM_EVT_PARAMS);
-       ALOGE("length=%d\n",length);
-       if(length <=0){
-         lib_running =0;
-       }
-       ALOGE("%s: Leaving userial_read_thread()", __func__);
-       pthread_exit(NULL);
-       return arg;
+    ALOGE("%s: Wait for events from the WCNSS Filter", __func__);
+    length = read_fm_event(fm_fd, evt_buf, sizeof(FM_EVT_HDR) + MAX_FM_EVT_PARAMS);
+    ALOGE("length=%d\n",length);
+    if(length <=0) {
+       lib_running =0;
+    }
+    ALOGE("%s: Leaving userial_read_thread()", __func__);
+    pthread_exit(NULL);
+    return arg;
 }
 
 /*
@@ -334,29 +337,37 @@
  */
 static void* fmHCITask(void *arg)
 {
-	static uint16_t events;
+    static uint16_t events;
+    uint16_t ret;
+    while (lib_running) {
+        pthread_mutex_lock(&fmHCIControlBlock.event_lock);
+        while (ready_events == 0) {
+            pthread_cond_wait(&fmHCIControlBlock.event_cond, &fmHCIControlBlock.event_lock);
+        }
+        events = ready_events;
+        ready_events = 0;
+        pthread_mutex_unlock(&fmHCIControlBlock.event_lock);
 
-	while (lib_running) {
-		pthread_mutex_lock(&fmHCIControlBlock.event_lock);
-		while (ready_events == 0) {
-			pthread_cond_wait(&fmHCIControlBlock.event_cond, &fmHCIControlBlock.event_lock);
-		}
+        if ((events & 0xFFF8) == HC_EVENT_TX) {
+        ALOGI("\n@@@@@ FM-HCI Task : EVENT_TX available @@@@@\n");
+        dequeue_fm_tx_cmd();
+        }
+        if ((events & 0xFFF4) == HC_EVENT_RX) {
+             ALOGI("\n##### FM-HCI Task : EVENT_RX available #####\n");
+        }
+    }
 
-		events = ready_events;
-		ready_events = 0;
-		pthread_mutex_unlock(&fmHCIControlBlock.event_lock);
-
-		if ((events & 0xFFF8) == HC_EVENT_TX) {
-			ALOGI("\n@@@@@ FM-HCI Task : EVENT_TX available @@@@@\n");
-			dequeue_fm_tx_cmd();
-		}
-		if ((events & 0xFFF4) == HC_EVENT_RX) {
-			ALOGI("\n##### FM-HCI Task : EVENT_RX available #####\n");
-			//TODO: Notify FM-HAL about event/data availablity
-		}
-	}
-        ALOGE("%s: ##### Exiting fmHCITask Worker thread!!! #####", __func__);
-	return arg;
+    ALOGE("%s: ##### Exiting fmHCITask Worker thread!!! #####", __func__);
+    ret = pthread_mutex_unlock(&fmHCIControlBlock.credit_lock);
+    ALOGE("%s: credit lock ret value =%d #####", __func__, ret);
+    pthread_mutex_destroy(&fmHCIControlBlock.credit_lock);
+    ret = pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
+    ALOGE("%s: tx queue lock ret value =%d #####", __func__, ret);
+    pthread_mutex_destroy(&fmHCIControlBlock.tx_q_lock);
+    ret = pthread_mutex_unlock(&fmHCIControlBlock.event_lock);
+    ALOGE("%s: event lock ret value =%d #####", __func__, ret);
+    pthread_mutex_destroy(&fmHCIControlBlock.event_lock);
+    return arg;
 }
 
 int fm_hci_init(fm_hal_cb *p_cb)
@@ -470,34 +481,34 @@
 void enqueue_fm_tx_cmd(FM_HDR *pbuf)
 {
 
-	pthread_mutex_lock(&fmHCIControlBlock.tx_q_lock);
+    pthread_mutex_lock(&fmHCIControlBlock.tx_q_lock);
 
-	if (!fmHCIControlBlock.first) {
-		fmHCIControlBlock.first = (TX_Q *) malloc(sizeof(TX_Q));
-		if (!fmHCIControlBlock.first) {
-			printf("Failed to allocate memory for first!!\n");
-			pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
-			return;
-		}
-		fmHCIControlBlock.first->hdr = pbuf;
-		fmHCIControlBlock.first->next = NULL;
-		fmHCIControlBlock.last = fmHCIControlBlock.first;
+    if (!fmHCIControlBlock.first) {
+        fmHCIControlBlock.first = (TX_Q *) malloc(sizeof(TX_Q));
+        if (!fmHCIControlBlock.first) {
+            printf("Failed to allocate memory for first!!\n");
+            pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
+            return;
+        }
+        fmHCIControlBlock.first->hdr = pbuf;
+        fmHCIControlBlock.first->next = NULL;
+        fmHCIControlBlock.last = fmHCIControlBlock.first;
                 ALOGI("%s: FM-CMD ENQUEUED SUCCESSFULLY", __func__);
-	} else {
-		TX_Q *element =  (TX_Q *) malloc(sizeof(TX_Q));
-		if (!element) {
-			printf("Failed to allocate memory for element!!\n");
-			pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
-			return;
-		}
-		fmHCIControlBlock.last->next = element;
-		element->hdr = pbuf;
-		element->next = NULL;
-		fmHCIControlBlock.last = element;
+    } else {
+        TX_Q *element =  (TX_Q *) malloc(sizeof(TX_Q));
+        if (!element) {
+            printf("Failed to allocate memory for element!!\n");
+            pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
+            return;
+        }
+        fmHCIControlBlock.last->next = element;
+        element->hdr = pbuf;
+        element->next = NULL;
+        fmHCIControlBlock.last = element;
                 ALOGI("%s: fm-cmd enqueued successfully", __func__);
-	}
+    }
 
-	pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
+    pthread_mutex_unlock(&fmHCIControlBlock.tx_q_lock);
 }
 
 /** Transmit frame */
@@ -510,8 +521,8 @@
 void userial_close_reader(void) {
     // Join the reader thread if it is still running.
     if (lib_running) {
-   //     send_event(USERIAL_RX_EXIT);
-        int result = pthread_join(&fmHCIControlBlock.fmRxTaskThreadId, NULL);
+        fm_send_event(USERIAL_RX_EXIT);
+        int result = pthread_join(fmHCIControlBlock.fmRxTaskThreadId, NULL);
         if (result)
             ALOGE("%s failed to join reader thread: %d", __func__, result);
         return;
@@ -520,13 +531,23 @@
 }
 
 void fm_userial_close(void) {
-   if (lib_running) {
-       int result = pthread_join(&fmHCIControlBlock.fmRxTaskThreadId, NULL);
-       if (result)
-           ALOGE("%s failed to join reader thread: %d", __func__, result);
-   }
-   fm_vnd_if->op(BT_VND_OP_FM_USERIAL_CLOSE, NULL);
-   // Free all buffers still waiting in the RX queue.
-   //  TODO: use list data structure and clean this up.
-   fm_fd = -1;
+
+    pthread_cond_signal(&fmHCIControlBlock.event_cond);
+    pthread_cond_destroy(&fmHCIControlBlock.event_cond);
+    pthread_cond_signal(&fmHCIControlBlock.cmd_credits_cond);
+    pthread_cond_destroy(&fmHCIControlBlock.cmd_credits_cond);
+
+    // Join the reader thread if it's still running.
+    if (lib_running) {
+        fm_send_event(USERIAL_RX_EXIT);
+        int result = pthread_join(fmHCIControlBlock.fmRxTaskThreadId, NULL);
+        if (result)
+            ALOGE("%s failed to join reader thread: %d", __func__, result);
+    }
+    lib_running =0;
+    ALOGE("%s  close fm userial ", __func__);
+    fm_vnd_if->op(BT_VND_OP_FM_USERIAL_CLOSE, NULL);
+    // Free all buffers still waiting in the RX queue.
+    //  TODO: use list data structure and clean this up.
+    fm_fd = -1;
 }
diff --git a/fm_hci/fm_hci.h b/fm_hci/fm_hci.h
index 431179b..8ffbf04 100644
--- a/fm_hci/fm_hci.h
+++ b/fm_hci/fm_hci.h
@@ -102,6 +102,7 @@
 int  fm_hci_init(fm_hal_cb *);
 void fm_power(fm_power_state state);
 int open_serial_port(void);
+void fm_userial_close(void);
 
 typedef struct {
     pthread_mutex_t tx_q_lock;