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/helium/radio-helium-commands.h b/helium/radio-helium-commands.h
index c480ea0..f76b7d2 100644
--- a/helium/radio-helium-commands.h
+++ b/helium/radio-helium-commands.h
@@ -76,6 +76,22 @@
     HCI_FM_HELIUM_DO_CALIBRATION,
     HCI_FM_HELIUM_SRCH_ALGORITHM,
     HCI_FM_HELIUM_GET_SINR,
+    HCI_FM_HELIUM_INTF_LOW_THRESHOLD,
+    HCI_FM_HELIUM_INTF_HIGH_THRESHOLD,
+    HCI_FM_HELIUM_SINR_THRESHOLD,
+    HCI_FM_HELIUM_SINR_SAMPLES,
+    HCI_FM_HELIUM_SPUR_FREQ,
+    HCI_FM_HELIUM_SPUR_FREQ_RMSSI,
+    HCI_FM_HELIUM_SPUR_SELECTION,
+    HCI_FM_HELIUM_UPDATE_SPUR_TABLE,
+    HCI_FM_HELIUM_VALID_CHANNEL,
+    HCI_FM_HELIUM_AF_RMSSI_TH,
+    HCI_FM_HELIUM_AF_RMSSI_SAMPLES,
+    HCI_FM_HELIUM_GOOD_CH_RMSSI_TH,
+    HCI_FM_HELIUM_SRCHALGOTYPE,
+    HCI_FM_HELIUM_CF0TH12,
+    HCI_FM_HELIUM_SINRFIRSTSTAGE,
+    HCI_FM_HELIUM_RMSSIFIRSTSTAGE,
     HCI_FM_HELIUM_RXREPEATCOUNT,
     HCI_FM_HELIUM_RSSI_TH,
     HCI_FM_HELIUM_AF_JUMP_RSSI_TH,
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 8599316..5c21bdd 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -160,6 +160,9 @@
 typedef void (*disable_cb)();
 typedef void (*callback_thread_event)(unsigned int evt);
 typedef void (*rds_grp_cntrs_cb)(char *rds_params);
+typedef void (*fm_peek_cb)(char *peek_rsp);
+typedef void (*fm_ssbi_peek_cb)(char *ssbi_peek_rsp);
+typedef void (*fm_ch_det_th_cb)(char *ch_det_rsp);
 
 typedef struct {
     size_t  size;
@@ -179,6 +182,9 @@
     ert_cb  ert_update_cb;
     disable_cb  disabled_cb;
     rds_grp_cntrs_cb rds_grp_cntrs_rsp_cb;
+    fm_peek_cb fm_peek_rsp_cb;
+    fm_ssbi_peek_cb fm_ssbi_peek_rsp_cb;
+    fm_ch_det_th_cb fm_ch_det_th_rsp_cb;
     callback_thread_event thread_evt_cb;
 } fm_vendor_callbacks_t;
 
@@ -499,7 +505,6 @@
 #define HCI_EV_RADIO_TEXT_PLUS_TAG      0x19
 #define HCI_EV_HW_ERR_EVENT             0x1A
 
-
 #define HCI_REQ_DONE      0
 #define HCI_REQ_PEND      1
 #define HCI_REQ_CANCELED  2
@@ -1157,5 +1162,34 @@
     enum hlm_region_t region;
     struct hci_fm_dbg_param_rsp st_dbg_param;
     struct hci_ev_srch_list_compl srch_st_result;
+    struct hci_fm_riva_poke   riva_data_req;
+    struct hci_fm_ssbi_req    ssbi_data_accs;
+    struct hci_fm_ssbi_peek   ssbi_peek_reg;
+    struct hci_fm_ch_det_threshold ch_det_threshold;
 };
+int hci_fm_disable_recv_req();
+int helium_search_list(struct hci_fm_search_station_list_req *s_list);
+int helium_search_rds_stations(struct hci_fm_search_rds_station_req *rds_srch);
+int helium_search_stations(struct hci_fm_search_station_req *srch);
+int helium_cancel_search_req();
+int hci_fm_set_recv_conf_req (struct hci_fm_recv_conf_req *conf);
+int hci_fm_get_program_service_req ();
+int hci_fm_get_rds_grpcounters_req (int val);
+int hci_fm_set_notch_filter_req (int val);
+int helium_set_sig_threshold_req(char th);
+int helium_rds_grp_mask_req(struct hci_fm_rds_grp_req *rds_grp_msk);
+int helium_rds_grp_process_req(int rds_grp);
+int helium_set_event_mask_req(char e_mask);
+int helium_set_antenna_req(char ant);
+int helium_set_fm_mute_mode_req(struct hci_fm_mute_mode_req *mute);
+int hci_fm_tune_station_req(int param);
+int hci_set_fm_stereo_mode_req(struct hci_fm_stereo_mode_req *param);
+int hci_peek_data(struct hci_fm_riva_data *data);
+int hci_poke_data(struct hci_fm_riva_poke *data);
+int hci_ssbi_poke_reg(struct hci_fm_ssbi_req *data);
+int hci_ssbi_peek_reg(struct hci_fm_ssbi_peek *data);
+int hci_fm_get_ch_det_th();
+int set_ch_det_thresholds_req(struct hci_fm_ch_det_threshold *ch_det_th);
+
+
 #endif /* __UAPI_RADIO_HCI_CORE_H */
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index a9aa9f0..fd673ab 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -29,6 +29,8 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
 #include <utils/Log.h>
 #include "radio-helium-commands.h"
 #include "radio-helium.h"
@@ -38,6 +40,7 @@
 fm_vendor_callbacks_t *jni_cb;
 int hci_fm_get_signal_threshold();
 int hci_fm_enable_recv_req();
+int hci_fm_mute_mode_req(struct hci_fm_mute_mode_req );
 struct helium_device *radio;
 static int oda_agt;
 static int grp_mask;
@@ -98,14 +101,18 @@
         ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
         return;
     }
+    ALOGE("%s:enetred %s calling ", LOG_TAG, __func__);
     status = (char) *ev_buff;
     radio_hci_req_complete(status);
     if (radio->mode == FM_TURNING_OFF) {
         jni_cb->disabled_cb();
         radio->mode = FM_OFF;
+        jni_cb->disabled_cb();
+        jni_cb->thread_evt_cb(1);
         //close the userial port and power off the chip
-      fm_userial_close();
-      fm_power(FM_RADIO_DISABLE);
+        ALOGE("%s:calling fm userial close\n", LOG_TAG );
+        fm_userial_close();
+    //  fm_power(FM_RADIO_DISABLE);
     }
 }
 
@@ -138,6 +145,57 @@
     jni_cb->rds_grp_cntrs_rsp_cb(&ev_buff[1]);
 }
 
+static void hci_cc_riva_peek_rsp(char *ev_buff)
+{
+    char status;
+
+    if (ev_buff == NULL) {
+        ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
+        return;
+    }
+    status = ev_buff[0];
+    ALOGE("%s:%s, status =%d\n", LOG_TAG, __func__,status);
+    if (status < 0) {
+        ALOGE("%s:%s, peek failed=%d\n", LOG_TAG, __func__, status);
+    }
+    jni_cb->fm_peek_rsp_cb(&ev_buff[PEEK_DATA_OFSET]);
+    radio_hci_req_complete(status);
+}
+
+static void hci_cc_ssbi_peek_rsp(char *ev_buff)
+{
+    char status;
+
+    if (ev_buff == NULL) {
+        ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
+        return;
+    }
+    status = ev_buff[0];
+    ALOGE("%s:%s, status =%d\n", LOG_TAG, __func__,status);
+    if (status < 0) {
+        ALOGE("%s:%s,ssbi peek failed=%d\n", LOG_TAG, __func__, status);
+    }
+    jni_cb->fm_ssbi_peek_rsp_cb(&ev_buff[PEEK_DATA_OFSET]);
+    radio_hci_req_complete(status);
+}
+
+static void hci_cc_get_ch_det_threshold_rsp(char *ev_buff)
+{
+    char status;
+
+    if (ev_buff == NULL) {
+        ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
+        return;
+    }
+    status = ev_buff[0];
+    ALOGE("%s:%s, status =%d\n", LOG_TAG, __func__,status);
+    if (status < 0) {
+        ALOGE("%s:%s,ssbi peek failed=%d\n", LOG_TAG, __func__, status);
+    }
+    memcpy(&radio->ch_det_threshold, &ev_buff[1],
+                        sizeof(struct hci_fm_ch_det_threshold));
+    radio_hci_req_complete(status);
+}
 
 static inline void hci_cmd_complete_event(char *buff)
 {
@@ -192,12 +250,18 @@
     case hci_status_param_op_pack(HCI_OCF_FM_READ_GRP_COUNTERS):
             hci_cc_rds_grp_cntrs_rsp(pbuf);
             break;
-/*    case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
-            hci_cc_get_spur_tbl(buff);
+    case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_PEEK_DATA):
+            hci_cc_riva_peek_rsp(buff);
             break;
     case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_PEEK_REG):
             hci_cc_ssbi_peek_rsp(buff);
             break;
+    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD):
+            hci_cc_get_ch_det_threshold_rsp(buff);
+            break;
+/*    case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
+            hci_cc_get_spur_tbl(buff);
+            break;
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_SIGNAL_THRESHOLD):
             hci_cc_sig_threshold_rsp(buff);
             break;
@@ -222,10 +286,6 @@
             hci_cc_riva_read_default_rsp(buff);
             break;
 
-    case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_PEEK_DATA):
-            hci_cc_riva_peek_rsp(buff);
-            break;
-
     case hci_common_cmd_op_pack(HCI_OCF_FM_GET_FEATURE_LIST):
             hci_cc_feature_list_rsp(buff);
             break;
@@ -240,9 +300,6 @@
             hci_cc_do_calibration_rsp(buff);
             break;
 
-    case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD):
-            hci_cc_get_ch_det_threshold_rsp(buff);
-            break;
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL):
             hci_cc_get_blend_tbl_rsp(buff);
             break;
@@ -364,6 +421,7 @@
 
     while ((buff[len+RDS_OFFSET] != 0x0d) && (len < MAX_RT_LENGTH))
            len++;
+    ALOGV("%s:%s: radio text length=%d\n", LOG_TAG, __func__,len);
     data = malloc(len+RDS_OFFSET);
     if (!data) {
         ALOGE("%s:Failed to allocate memory", LOG_TAG);
@@ -521,7 +579,8 @@
 {
    ALOGE("%s:%s: start", LOG_TAG, __func__);
    jni_cb->disabled_cb();
-    fm_userial_close();
+   jni_cb->thread_evt_cb(1);
+   fm_userial_close();
 }
 
 static void hci_buff_ert(struct rds_grp_data *rds_buf)
@@ -646,7 +705,7 @@
          //    hci_ev_rt_plus(temp);
         }
         else if (carrier == ert_carrier) {
-             ALOGE("%s:: calling event ert", __func__);
+             ALOGI("%s:: calling event ert", __func__);
              hci_buff_ert(&temp);
        }
     }
@@ -711,9 +770,9 @@
     case HCI_EV_RADIO_TEXT_PLUS_TAG:
         hci_ev_rt_plus_tag(((FM_EVT_HDR *)evt_buf)->cmd_params);
         break;
-	case HCI_EV_HW_ERR_EVENT:
-		hci_ev_hw_error(((FM_EVT_HDR *)evt_buf)->cmd_params);
-		break;
+    case HCI_EV_HW_ERR_EVENT:
+	    hci_ev_hw_error(((FM_EVT_HDR *)evt_buf)->cmd_params);
+	    break;
     default:
         break;
     }
@@ -1063,6 +1122,125 @@
         radio->stereo_mode.stereo_mode = ~val;
         hci_set_fm_stereo_mode_req(&radio->stereo_mode);
         break;
+    case HCI_FM_HELIUM_RIVA_ACCS_ADDR:
+        radio->riva_data_req.cmd_params.start_addr = val;
+        break;
+    case HCI_FM_HELIUM_RIVA_ACCS_LEN:
+        if (is_valid_peek_len(val)) {
+            radio->riva_data_req.cmd_params.length = val;
+        } else {
+            ret = -1;
+            ALOGE("%s: riva access len is not valid\n", LOG_TAG);
+            goto END;
+        }
+        break;
+    case HCI_FM_HELIUM_RIVA_PEEK:
+        radio->riva_data_req.cmd_params.subopcode = RIVA_PEEK_OPCODE;
+        val = hci_peek_data(&radio->riva_data_req.cmd_params);
+        break;
+    case HCI_FM_HELIUM_RIVA_POKE:
+         if (radio->riva_data_req.cmd_params.length <=
+                    MAX_RIVA_PEEK_RSP_SIZE) {
+             radio->riva_data_req.cmd_params.subopcode =
+                                                RIVA_POKE_OPCODE;
+             ret = hci_poke_data(&radio->riva_data_req);
+         } else {
+             ALOGE("%s: riva access len is not valid for poke\n", LOG_TAG);
+             ret = -1;
+             goto END;
+         }
+         break;
+    case HCI_FM_HELIUM_SSBI_ACCS_ADDR:
+        radio->ssbi_data_accs.start_addr = val;
+        break;
+    case HCI_FM_HELIUM_SSBI_POKE:
+        radio->ssbi_data_accs.data = val;
+        ret = hci_ssbi_poke_reg(&radio->ssbi_data_accs);
+        break;
+    case HCI_FM_HELIUM_SSBI_PEEK:
+        radio->ssbi_peek_reg.start_address = val;
+        hci_ssbi_peek_reg(&radio->ssbi_peek_reg);
+        break;
+    case HCI_FM_HELIUM_SINR_SAMPLES:
+         if (!is_valid_sinr_samples(val)) {
+             ALOGE("%s: sinr samples count is not valid\n", __func__);
+             ret = -1;
+             goto END;
+         }
+         ret = hci_fm_get_ch_det_th();
+         if (ret < 0) {
+             ALOGE("Failed to get chnl det thresholds  %d", ret);
+             goto END;
+         }
+         saved_val = radio->ch_det_threshold.sinr_samples;
+         radio->ch_det_threshold.sinr_samples = val;
+         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         if (ret < 0) {
+             ALOGE("Failed to set SINR samples  %d", ret);
+             radio->ch_det_threshold.sinr_samples = saved_val;
+             goto END;
+         }
+         break;
+    case HCI_FM_HELIUM_SINR_THRESHOLD:
+         if (!is_valid_sinr_th(val)) {
+             ALOGE("%s: sinr threshold is not valid\n");
+             ret = -1;
+             goto END;
+         }
+         ret = hci_fm_get_ch_det_th();
+         if (ret < 0) {
+             ALOGE("Failed to get chnl det thresholds  %d", ret);
+             goto END;
+         }
+         saved_val = radio->ch_det_threshold.sinr;
+         radio->ch_det_threshold.sinr = val;
+         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         if (ret < 0) {
+             ALOGE("Failed to set SINR threshold %d", ret);
+             radio->ch_det_threshold.sinr = saved_val;
+             goto END;
+         }
+         break;
+    case HCI_FM_HELIUM_INTF_LOW_THRESHOLD:
+         if (!is_valid_intf_det_low_th(val)) {
+             ALOGE("%s: intf det low threshold is not valid\n", __func__);
+             ret = -1;
+             goto END;
+         }
+         ret = hci_fm_get_ch_det_th();
+         if (ret < 0) {
+             ALOGE("Failed to get chnl det thresholds  %d", ret);
+             goto END;
+         }
+         saved_val = radio->ch_det_threshold.low_th;
+         radio->ch_det_threshold.low_th = val;
+         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         if (ret < 0) {
+             ALOGE("Failed to Set Low det threshold %d", ret);
+             radio->ch_det_threshold.low_th = saved_val;
+             goto END;
+         }
+         break;
+    case HCI_FM_HELIUM_INTF_HIGH_THRESHOLD:
+         if (!is_valid_intf_det_hgh_th(val)) {
+             ALOGE("%s: intf high threshold is not valid\n", __func__);
+             ret = -1;
+             goto END;
+         }
+         ret = hci_fm_get_ch_det_th();
+         if (ret < 0) {
+             ALOGE("Failed to get chnl det thresholds  %d", ret);
+             goto END;
+         }
+         saved_val = radio->ch_det_threshold.high_th;
+         radio->ch_det_threshold.high_th = val;
+         ret = set_ch_det_thresholds_req(&radio->ch_det_threshold);
+         if (ret < 0) {
+             ALOGE("Failed to set High det threshold %d ", ret);
+             radio->ch_det_threshold.high_th = saved_val;
+             goto END;
+         }
+         break;
     default:
         ALOGE("%s:%s: Not a valid FM CMD!!", LOG_TAG, __func__);
         ret = 0;
@@ -1088,6 +1266,26 @@
     case HCI_FM_HELIUM_LOWER_BAND:
         val = radio->recv_conf.band_low_limit;
         break;
+    case HCI_FM_HELIUM_SINR_SAMPLES:
+        ret = hci_fm_get_ch_det_th();
+         if (ret == 0)
+             val = radio->ch_det_threshold.sinr_samples;
+        break;
+    case HCI_FM_HELIUM_SINR_THRESHOLD:
+        ret = hci_fm_get_ch_det_th();
+        if (ret == 0)
+            val = radio->ch_det_threshold.sinr;
+        break;
+    case HCI_FM_HELIUM_INTF_LOW_THRESHOLD:
+        ret = hci_fm_get_ch_det_th();
+        if (ret == 0)
+            val = radio->ch_det_threshold.low_th;
+        break;
+    case HCI_FM_HELIUM_INTF_HIGH_THRESHOLD:
+        ret = hci_fm_get_ch_det_th();
+        if (ret == 0)
+            val = radio->ch_det_threshold.high_th;
+        break;
     default:
         break;
     }
diff --git a/helium/radio_helium_hal_cmds.c b/helium/radio_helium_hal_cmds.c
index 1d422d1..df79d75 100644
--- a/helium/radio_helium_hal_cmds.c
+++ b/helium/radio_helium_hal_cmds.c
@@ -29,6 +29,9 @@
 
 #include <stdio.h>
 #include <utils/Log.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
 #include "radio-helium-commands.h"
 #include "radio-helium.h"
 #include "fm_hci.h"
@@ -282,3 +285,74 @@
                                               stereo_mode_req);
 }
 
+int hci_peek_data(struct hci_fm_riva_data *data)
+{
+    uint16_t opcode = 0;
+
+    if (data == NULL) {
+        ALOGE("%s:%s, peek data req is null\n", LOG_TAG, __func__);
+        return -1;
+    }
+    opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+                HCI_OCF_FM_PEEK_DATA);
+    return send_fm_cmd_pkt(opcode, sizeof((*data)), data);
+}
+
+int hci_poke_data(struct hci_fm_riva_poke *data)
+{
+    uint16_t opcode = 0;
+
+    if (data == NULL) {
+        ALOGE("%s:%s, poke data req is null\n", LOG_TAG, __func__);
+        return -1;
+    }
+    opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+                HCI_OCF_FM_POKE_DATA);
+    return send_fm_cmd_pkt(opcode, sizeof((*data)), data);
+}
+
+int hci_ssbi_poke_reg(struct hci_fm_ssbi_req *data)
+{
+    uint16_t opcode = 0;
+
+    if (data == NULL) {
+        ALOGE("%s:%s,SSBI poke data req is null\n", LOG_TAG, __func__);
+        return -1;
+    }
+    opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+                HCI_OCF_FM_SSBI_POKE_REG);
+    return send_fm_cmd_pkt(opcode, sizeof((*data)), data);
+}
+
+int hci_ssbi_peek_reg(struct hci_fm_ssbi_peek *data)
+{
+    uint16_t opcode = 0;
+
+    if (data == NULL) {
+        ALOGE("%s:%s,SSBI peek data req is null\n", LOG_TAG, __func__);
+        return -1;
+    }
+    opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+                HCI_OCF_FM_SSBI_PEEK_REG);
+   return send_fm_cmd_pkt(opcode, sizeof((*data)), data);
+}
+
+int hci_fm_get_ch_det_th()
+{
+    uint16_t opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+			HCI_OCF_FM_GET_CH_DET_THRESHOLD);
+    return send_fm_cmd_pkt(opcode, 0, NULL);
+}
+
+int set_ch_det_thresholds_req(struct hci_fm_ch_det_threshold *ch_det_th)
+{
+    uint16_t opcode = 0;
+
+    if (ch_det_th == NULL) {
+        ALOGE("%s,%s channel det thrshld is null\n", LOG_TAG,  __func__);
+        return -1;
+    }
+    opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+                            HCI_OCF_FM_SET_CH_DET_THRESHOLD);
+    return send_fm_cmd_pkt(opcode, sizeof((*ch_det_th)), ch_det_th);
+}