147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo/* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
234ee09551764b045fdc02df754157473125edf60Kevin Tang *
334ee09551764b045fdc02df754157473125edf60Kevin Tang * Redistribution and use in source and binary forms, with or without
434ee09551764b045fdc02df754157473125edf60Kevin Tang * modification, are permitted provided that the following conditions are
534ee09551764b045fdc02df754157473125edf60Kevin Tang * met:
634ee09551764b045fdc02df754157473125edf60Kevin Tang *     * Redistributions of source code must retain the above copyright
734ee09551764b045fdc02df754157473125edf60Kevin Tang *       notice, this list of conditions and the following disclaimer.
834ee09551764b045fdc02df754157473125edf60Kevin Tang *     * Redistributions in binary form must reproduce the above
934ee09551764b045fdc02df754157473125edf60Kevin Tang *       copyright notice, this list of conditions and the following
1034ee09551764b045fdc02df754157473125edf60Kevin Tang *       disclaimer in the documentation and/or other materials provided
1134ee09551764b045fdc02df754157473125edf60Kevin Tang *       with the distribution.
12e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *     * Neither the name of The Linux Foundation, nor the names of its
1334ee09551764b045fdc02df754157473125edf60Kevin Tang *       contributors may be used to endorse or promote products derived
1434ee09551764b045fdc02df754157473125edf60Kevin Tang *       from this software without specific prior written permission.
1534ee09551764b045fdc02df754157473125edf60Kevin Tang *
1634ee09551764b045fdc02df754157473125edf60Kevin Tang * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
1734ee09551764b045fdc02df754157473125edf60Kevin Tang * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1834ee09551764b045fdc02df754157473125edf60Kevin Tang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
1934ee09551764b045fdc02df754157473125edf60Kevin Tang * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
2034ee09551764b045fdc02df754157473125edf60Kevin Tang * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2134ee09551764b045fdc02df754157473125edf60Kevin Tang * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2234ee09551764b045fdc02df754157473125edf60Kevin Tang * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2334ee09551764b045fdc02df754157473125edf60Kevin Tang * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2434ee09551764b045fdc02df754157473125edf60Kevin Tang * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2534ee09551764b045fdc02df754157473125edf60Kevin Tang * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2634ee09551764b045fdc02df754157473125edf60Kevin Tang * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2734ee09551764b045fdc02df754157473125edf60Kevin Tang *
2834ee09551764b045fdc02df754157473125edf60Kevin Tang */
2934ee09551764b045fdc02df754157473125edf60Kevin Tang
3034ee09551764b045fdc02df754157473125edf60Kevin Tang#define LOG_NDDEBUG 0
3134ee09551764b045fdc02df754157473125edf60Kevin Tang#define LOG_TAG "LocSvc_eng"
3234ee09551764b045fdc02df754157473125edf60Kevin Tang
3334ee09551764b045fdc02df754157473125edf60Kevin Tang#include <stdio.h>
3434ee09551764b045fdc02df754157473125edf60Kevin Tang#include <stdlib.h>
3534ee09551764b045fdc02df754157473125edf60Kevin Tang#include <sys/time.h>
3634ee09551764b045fdc02df754157473125edf60Kevin Tang#include <pthread.h>
3734ee09551764b045fdc02df754157473125edf60Kevin Tang#include <errno.h>
3834ee09551764b045fdc02df754157473125edf60Kevin Tang#include <string.h>
3934ee09551764b045fdc02df754157473125edf60Kevin Tang#include <ctype.h>
4034ee09551764b045fdc02df754157473125edf60Kevin Tang#include <unistd.h>
4134ee09551764b045fdc02df754157473125edf60Kevin Tang#include <time.h>
42e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <MsgTask.h>
4334ee09551764b045fdc02df754157473125edf60Kevin Tang
4434ee09551764b045fdc02df754157473125edf60Kevin Tang#include <loc_eng.h>
4534ee09551764b045fdc02df754157473125edf60Kevin Tang
4634ee09551764b045fdc02df754157473125edf60Kevin Tang#include "log_util.h"
47e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include "platform_lib_includes.h"
48e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
49e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russousing namespace loc_core;
5034ee09551764b045fdc02df754157473125edf60Kevin Tang
5134ee09551764b045fdc02df754157473125edf60Kevin Tang/*=============================================================================
5234ee09551764b045fdc02df754157473125edf60Kevin Tang *
5334ee09551764b045fdc02df754157473125edf60Kevin Tang *                             DATA DECLARATION
5434ee09551764b045fdc02df754157473125edf60Kevin Tang *
5534ee09551764b045fdc02df754157473125edf60Kevin Tang *============================================================================*/
5634ee09551764b045fdc02df754157473125edf60Kevin Tang
5734ee09551764b045fdc02df754157473125edf60Kevin Tang/*=============================================================================
5834ee09551764b045fdc02df754157473125edf60Kevin Tang *
5934ee09551764b045fdc02df754157473125edf60Kevin Tang *                             FUNCTION DECLARATIONS
6034ee09551764b045fdc02df754157473125edf60Kevin Tang *
6134ee09551764b045fdc02df754157473125edf60Kevin Tang *============================================================================*/
6234ee09551764b045fdc02df754157473125edf60Kevin Tangstatic void* ni_thread_proc(void *args);
6334ee09551764b045fdc02df754157473125edf60Kevin Tang
64e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russostruct LocEngInformNiResponse : public LocMsg {
65e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LocEngAdapter* mAdapter;
66e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    const GpsUserResponseType mResponse;
67e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    const void *mPayload;
68e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    inline LocEngInformNiResponse(LocEngAdapter* adapter,
69e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                  GpsUserResponseType resp,
70e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                                  const void* data) :
71e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LocMsg(), mAdapter(adapter),
72e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mResponse(resp), mPayload(data)
73e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
74e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        locallog();
75e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
76e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    inline ~LocEngInformNiResponse()
77e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
78e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        // this is a bit weird since mPayload is not
79e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        // allocated by this class.  But there is no better way.
80e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        // mPayload actually won't be NULL here.
81e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        free((void*)mPayload);
82e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
83e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    inline virtual void proc() const
84e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
85e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        mAdapter->informNiResponse(mResponse, mPayload);
86e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
87e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    inline void locallog() const
88e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
89e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGV("LocEngInformNiResponse - "
90e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                 "response: %s\n  mPayload: %p",
91e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                 loc_get_ni_response_name(mResponse),
92e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                 mPayload);
93e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
94e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    inline virtual void log() const
95e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    {
96e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        locallog();
97e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
98e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo};
99e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
10034ee09551764b045fdc02df754157473125edf60Kevin Tang/*===========================================================================
10134ee09551764b045fdc02df754157473125edf60Kevin Tang
10234ee09551764b045fdc02df754157473125edf60Kevin TangFUNCTION loc_eng_ni_request_handler
10334ee09551764b045fdc02df754157473125edf60Kevin Tang
10434ee09551764b045fdc02df754157473125edf60Kevin TangDESCRIPTION
10534ee09551764b045fdc02df754157473125edf60Kevin Tang   Displays the NI request and awaits user input. If a previous request is
10634ee09551764b045fdc02df754157473125edf60Kevin Tang   in session, it is ignored.
10734ee09551764b045fdc02df754157473125edf60Kevin Tang
10834ee09551764b045fdc02df754157473125edf60Kevin TangRETURN VALUE
10934ee09551764b045fdc02df754157473125edf60Kevin Tang   none
11034ee09551764b045fdc02df754157473125edf60Kevin Tang
11134ee09551764b045fdc02df754157473125edf60Kevin Tang===========================================================================*/
11234ee09551764b045fdc02df754157473125edf60Kevin Tangvoid loc_eng_ni_request_handler(loc_eng_data_s_type &loc_eng_data,
11334ee09551764b045fdc02df754157473125edf60Kevin Tang                            const GpsNiNotification *notif,
11434ee09551764b045fdc02df754157473125edf60Kevin Tang                            const void* passThrough)
11534ee09551764b045fdc02df754157473125edf60Kevin Tang{
11634ee09551764b045fdc02df754157473125edf60Kevin Tang    ENTRY_LOG();
11734ee09551764b045fdc02df754157473125edf60Kevin Tang    char lcs_addr[32]; // Decoded LCS address for UMTS CP NI
11834ee09551764b045fdc02df754157473125edf60Kevin Tang    loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
11947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    loc_eng_ni_session_s_type* pSession = NULL;
12034ee09551764b045fdc02df754157473125edf60Kevin Tang
12134ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL == loc_eng_data.ni_notify_cb) {
12234ee09551764b045fdc02df754157473125edf60Kevin Tang        EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
12334ee09551764b045fdc02df754157473125edf60Kevin Tang        return;
12434ee09551764b045fdc02df754157473125edf60Kevin Tang    }
12534ee09551764b045fdc02df754157473125edf60Kevin Tang
12647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (notif->ni_type == GPS_NI_TYPE_EMERGENCY_SUPL) {
12747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
12847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            LOC_LOGW("loc_eng_ni_request_handler, supl es NI in progress, new supl es NI ignored, type: %d",
12947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                     notif->ni_type);
13047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            if (NULL != passThrough) {
13147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                free((void*)passThrough);
13247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            }
13347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        } else {
13447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            pSession = &loc_eng_ni_data_p->sessionEs;
13547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        }
13647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    } else {
13747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        if (NULL != loc_eng_ni_data_p->session.rawRequest ||
13847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
13947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            LOC_LOGW("loc_eng_ni_request_handler, supl NI in progress, new supl NI ignored, type: %d",
14047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                     notif->ni_type);
14147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            if (NULL != passThrough) {
14247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                free((void*)passThrough);
14347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            }
14447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        } else {
14547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            pSession = &loc_eng_ni_data_p->session;
14634ee09551764b045fdc02df754157473125edf60Kevin Tang        }
14734ee09551764b045fdc02df754157473125edf60Kevin Tang    }
14847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
14947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
15047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (pSession) {
15134ee09551764b045fdc02df754157473125edf60Kevin Tang        /* Save request */
15247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->rawRequest = (void*)passThrough;
15347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->reqID = ++loc_eng_ni_data_p->reqIDCounter;
15447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->adapter = loc_eng_data.adapter;
15534ee09551764b045fdc02df754157473125edf60Kevin Tang
15634ee09551764b045fdc02df754157473125edf60Kevin Tang        /* Fill in notification */
15747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        ((GpsNiNotification*)notif)->notification_id = pSession->reqID;
15834ee09551764b045fdc02df754157473125edf60Kevin Tang
15934ee09551764b045fdc02df754157473125edf60Kevin Tang        if (notif->notify_flags == GPS_NI_PRIVACY_OVERRIDE)
16034ee09551764b045fdc02df754157473125edf60Kevin Tang        {
16134ee09551764b045fdc02df754157473125edf60Kevin Tang            loc_eng_mute_one_session(loc_eng_data);
16234ee09551764b045fdc02df754157473125edf60Kevin Tang        }
16334ee09551764b045fdc02df754157473125edf60Kevin Tang
16434ee09551764b045fdc02df754157473125edf60Kevin Tang        /* Log requestor ID and text for debugging */
16534ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGI("Notification: notif_type: %d, timeout: %d, default_resp: %d", notif->ni_type, notif->timeout, notif->default_response);
16634ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGI("              requestor_id: %s (encoding: %d)", notif->requestor_id, notif->requestor_id_encoding);
16734ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGI("              text: %s text (encoding: %d)", notif->text, notif->text_encoding);
16834ee09551764b045fdc02df754157473125edf60Kevin Tang        if (notif->extras[0])
16934ee09551764b045fdc02df754157473125edf60Kevin Tang        {
17034ee09551764b045fdc02df754157473125edf60Kevin Tang            LOC_LOGI("              extras: %s", notif->extras);
17134ee09551764b045fdc02df754157473125edf60Kevin Tang        }
17234ee09551764b045fdc02df754157473125edf60Kevin Tang
17334ee09551764b045fdc02df754157473125edf60Kevin Tang        /* For robustness, spawn a thread at this point to timeout to clear up the notification status, even though
17434ee09551764b045fdc02df754157473125edf60Kevin Tang         * the OEM layer in java does not do so.
17534ee09551764b045fdc02df754157473125edf60Kevin Tang         **/
17647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->respTimeLeft = 5 + (notif->timeout != 0 ? notif->timeout : LOC_NI_NO_RESPONSE_TIME);
17747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        LOC_LOGI("Automatically sends 'no response' in %d seconds (to clear status)\n", pSession->respTimeLeft);
17834ee09551764b045fdc02df754157473125edf60Kevin Tang
17934ee09551764b045fdc02df754157473125edf60Kevin Tang        int rc = 0;
18047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        rc = pthread_create(&pSession->thread, NULL, ni_thread_proc, pSession);
18134ee09551764b045fdc02df754157473125edf60Kevin Tang        if (rc)
18234ee09551764b045fdc02df754157473125edf60Kevin Tang        {
18334ee09551764b045fdc02df754157473125edf60Kevin Tang            LOC_LOGE("Loc NI thread is not created.\n");
18434ee09551764b045fdc02df754157473125edf60Kevin Tang        }
18547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        rc = pthread_detach(pSession->thread);
18634ee09551764b045fdc02df754157473125edf60Kevin Tang        if (rc)
18734ee09551764b045fdc02df754157473125edf60Kevin Tang        {
18834ee09551764b045fdc02df754157473125edf60Kevin Tang            LOC_LOGE("Loc NI thread is not detached.\n");
18934ee09551764b045fdc02df754157473125edf60Kevin Tang        }
19034ee09551764b045fdc02df754157473125edf60Kevin Tang
19134ee09551764b045fdc02df754157473125edf60Kevin Tang        CALLBACK_LOG_CALLFLOW("ni_notify_cb - id", %d, notif->notification_id);
19234ee09551764b045fdc02df754157473125edf60Kevin Tang        loc_eng_data.ni_notify_cb((GpsNiNotification*)notif);
19334ee09551764b045fdc02df754157473125edf60Kevin Tang    }
19434ee09551764b045fdc02df754157473125edf60Kevin Tang    EXIT_LOG(%s, VOID_RET);
19534ee09551764b045fdc02df754157473125edf60Kevin Tang}
19634ee09551764b045fdc02df754157473125edf60Kevin Tang
19734ee09551764b045fdc02df754157473125edf60Kevin Tang/*===========================================================================
19834ee09551764b045fdc02df754157473125edf60Kevin Tang
19934ee09551764b045fdc02df754157473125edf60Kevin TangFUNCTION ni_thread_proc
20034ee09551764b045fdc02df754157473125edf60Kevin Tang
20134ee09551764b045fdc02df754157473125edf60Kevin Tang===========================================================================*/
20234ee09551764b045fdc02df754157473125edf60Kevin Tangstatic void* ni_thread_proc(void *args)
20334ee09551764b045fdc02df754157473125edf60Kevin Tang{
20434ee09551764b045fdc02df754157473125edf60Kevin Tang    ENTRY_LOG();
20534ee09551764b045fdc02df754157473125edf60Kevin Tang
20647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    loc_eng_ni_session_s_type* pSession = (loc_eng_ni_session_s_type*)args;
20734ee09551764b045fdc02df754157473125edf60Kevin Tang    int rc = 0;          /* return code from pthread calls */
20834ee09551764b045fdc02df754157473125edf60Kevin Tang
20934ee09551764b045fdc02df754157473125edf60Kevin Tang    struct timeval present_time;
21034ee09551764b045fdc02df754157473125edf60Kevin Tang    struct timespec expire_time;
21134ee09551764b045fdc02df754157473125edf60Kevin Tang
21234ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("Starting Loc NI thread...\n");
21347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    pthread_mutex_lock(&pSession->tLock);
21434ee09551764b045fdc02df754157473125edf60Kevin Tang    /* Calculate absolute expire time */
21534ee09551764b045fdc02df754157473125edf60Kevin Tang    gettimeofday(&present_time, NULL);
21647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    expire_time.tv_sec  = present_time.tv_sec + pSession->respTimeLeft;
21734ee09551764b045fdc02df754157473125edf60Kevin Tang    expire_time.tv_nsec = present_time.tv_usec * 1000;
21834ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("ni_thread_proc-Time out set for abs time %ld with delay %d sec\n",
21947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo             (long) expire_time.tv_sec, pSession->respTimeLeft );
22034ee09551764b045fdc02df754157473125edf60Kevin Tang
22147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    while (!pSession->respRecvd)
22234ee09551764b045fdc02df754157473125edf60Kevin Tang    {
22347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        rc = pthread_cond_timedwait(&pSession->tCond,
22447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                                    &pSession->tLock,
22534ee09551764b045fdc02df754157473125edf60Kevin Tang                                    &expire_time);
22634ee09551764b045fdc02df754157473125edf60Kevin Tang        if (rc == ETIMEDOUT)
22734ee09551764b045fdc02df754157473125edf60Kevin Tang        {
22847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            pSession->resp = GPS_NI_RESPONSE_NORESP;
22934ee09551764b045fdc02df754157473125edf60Kevin Tang            LOC_LOGD("ni_thread_proc-Thread time out after valting for specified time. Ret Val %d\n",rc );
23034ee09551764b045fdc02df754157473125edf60Kevin Tang            break;
23134ee09551764b045fdc02df754157473125edf60Kevin Tang        }
23234ee09551764b045fdc02df754157473125edf60Kevin Tang    }
23334ee09551764b045fdc02df754157473125edf60Kevin Tang    LOC_LOGD("ni_thread_proc-Java layer has sent us a user response and return value from "
23434ee09551764b045fdc02df754157473125edf60Kevin Tang             "pthread_cond_timedwait = %d\n",rc );
23547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    pSession->respRecvd = FALSE; /* Reset the user response flag for the next session*/
23647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
23747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    LOC_LOGD("pSession->resp is %d\n",pSession->resp);
23834ee09551764b045fdc02df754157473125edf60Kevin Tang
23934ee09551764b045fdc02df754157473125edf60Kevin Tang    // adding this check to support modem restart, in which case, we need the thread
240e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    // to exit without calling sending data. We made sure that rawRequest is NULL in
241e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    // loc_eng_ni_reset_on_engine_restart()
24247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    LocEngAdapter* adapter = pSession->adapter;
243e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LocEngInformNiResponse *msg = NULL;
24434ee09551764b045fdc02df754157473125edf60Kevin Tang
24547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (NULL != pSession->rawRequest) {
24647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        if (pSession->resp != GPS_NI_RESPONSE_IGNORE) {
24747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            LOC_LOGD("pSession->resp != GPS_NI_RESPONSE_IGNORE \n");
24847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            msg = new LocEngInformNiResponse(adapter,
24947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                                             pSession->resp,
25047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                                             pSession->rawRequest);
25147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        } else {
25247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            LOC_LOGD("this is the ignore reply for SUPL ES\n");
25347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            free(pSession->rawRequest);
25447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        }
25547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->rawRequest = NULL;
25634ee09551764b045fdc02df754157473125edf60Kevin Tang    }
25747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    pthread_mutex_unlock(&pSession->tLock);
25834ee09551764b045fdc02df754157473125edf60Kevin Tang
25947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    pSession->respTimeLeft = 0;
26047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    pSession->reqID = 0;
26134ee09551764b045fdc02df754157473125edf60Kevin Tang
26234ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL != msg) {
26347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        LOC_LOGD("ni_thread_proc: adapter->sendMsg(msg)\n");
264e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        adapter->sendMsg(msg);
26534ee09551764b045fdc02df754157473125edf60Kevin Tang    }
26634ee09551764b045fdc02df754157473125edf60Kevin Tang
26734ee09551764b045fdc02df754157473125edf60Kevin Tang    EXIT_LOG(%s, VOID_RET);
26834ee09551764b045fdc02df754157473125edf60Kevin Tang    return NULL;
26934ee09551764b045fdc02df754157473125edf60Kevin Tang}
27034ee09551764b045fdc02df754157473125edf60Kevin Tang
27134ee09551764b045fdc02df754157473125edf60Kevin Tangvoid loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data)
27234ee09551764b045fdc02df754157473125edf60Kevin Tang{
27334ee09551764b045fdc02df754157473125edf60Kevin Tang    ENTRY_LOG();
27434ee09551764b045fdc02df754157473125edf60Kevin Tang    loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
27534ee09551764b045fdc02df754157473125edf60Kevin Tang
27634ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL == loc_eng_data.ni_notify_cb) {
27734ee09551764b045fdc02df754157473125edf60Kevin Tang        EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
27834ee09551764b045fdc02df754157473125edf60Kevin Tang        return;
27934ee09551764b045fdc02df754157473125edf60Kevin Tang    }
28034ee09551764b045fdc02df754157473125edf60Kevin Tang
28134ee09551764b045fdc02df754157473125edf60Kevin Tang    // only if modem has requested but then died.
28247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
28347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        free(loc_eng_ni_data_p->sessionEs.rawRequest);
28447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->sessionEs.rawRequest = NULL;
28534ee09551764b045fdc02df754157473125edf60Kevin Tang
28647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_lock(&loc_eng_ni_data_p->sessionEs.tLock);
28734ee09551764b045fdc02df754157473125edf60Kevin Tang        // the goal is to wake up ni_thread_proc
28834ee09551764b045fdc02df754157473125edf60Kevin Tang        // and let it exit.
28947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->sessionEs.respRecvd = TRUE;
29047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_cond_signal(&loc_eng_ni_data_p->sessionEs.tCond);
29147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_unlock(&loc_eng_ni_data_p->sessionEs.tLock);
29247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    }
29347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
29447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (NULL != loc_eng_ni_data_p->session.rawRequest) {
29547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        free(loc_eng_ni_data_p->session.rawRequest);
29647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->session.rawRequest = NULL;
29747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
29847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock);
29947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        // the goal is to wake up ni_thread_proc
30047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        // and let it exit.
30147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->session.respRecvd = TRUE;
30247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_cond_signal(&loc_eng_ni_data_p->session.tCond);
30347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock);
30434ee09551764b045fdc02df754157473125edf60Kevin Tang    }
30534ee09551764b045fdc02df754157473125edf60Kevin Tang
30634ee09551764b045fdc02df754157473125edf60Kevin Tang    EXIT_LOG(%s, VOID_RET);
30734ee09551764b045fdc02df754157473125edf60Kevin Tang}
30834ee09551764b045fdc02df754157473125edf60Kevin Tang
30934ee09551764b045fdc02df754157473125edf60Kevin Tang/*===========================================================================
31034ee09551764b045fdc02df754157473125edf60Kevin TangFUNCTION    loc_eng_ni_init
31134ee09551764b045fdc02df754157473125edf60Kevin Tang
31234ee09551764b045fdc02df754157473125edf60Kevin TangDESCRIPTION
31334ee09551764b045fdc02df754157473125edf60Kevin Tang   This function initializes the NI interface
31434ee09551764b045fdc02df754157473125edf60Kevin Tang
31534ee09551764b045fdc02df754157473125edf60Kevin TangDEPENDENCIES
31634ee09551764b045fdc02df754157473125edf60Kevin Tang   NONE
31734ee09551764b045fdc02df754157473125edf60Kevin Tang
31834ee09551764b045fdc02df754157473125edf60Kevin TangRETURN VALUE
31934ee09551764b045fdc02df754157473125edf60Kevin Tang   None
32034ee09551764b045fdc02df754157473125edf60Kevin Tang
32134ee09551764b045fdc02df754157473125edf60Kevin TangSIDE EFFECTS
32234ee09551764b045fdc02df754157473125edf60Kevin Tang   N/A
32334ee09551764b045fdc02df754157473125edf60Kevin Tang
32434ee09551764b045fdc02df754157473125edf60Kevin Tang===========================================================================*/
325e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data, GpsNiExtCallbacks *callbacks)
32634ee09551764b045fdc02df754157473125edf60Kevin Tang{
32734ee09551764b045fdc02df754157473125edf60Kevin Tang    ENTRY_LOG_CALLFLOW();
32834ee09551764b045fdc02df754157473125edf60Kevin Tang
329e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if(callbacks == NULL)
330e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        EXIT_LOG(%s, "loc_eng_ni_init: failed, cb is NULL");
331e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    else if (NULL == callbacks->notify_cb) {
33234ee09551764b045fdc02df754157473125edf60Kevin Tang        EXIT_LOG(%s, "loc_eng_ni_init: failed, no cb.");
33334ee09551764b045fdc02df754157473125edf60Kevin Tang    } else if (NULL != loc_eng_data.ni_notify_cb) {
33434ee09551764b045fdc02df754157473125edf60Kevin Tang        EXIT_LOG(%s, "loc_eng_ni_init: already inited.");
33534ee09551764b045fdc02df754157473125edf60Kevin Tang    } else {
33634ee09551764b045fdc02df754157473125edf60Kevin Tang        loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
33747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->sessionEs.respTimeLeft = 0;
33847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->sessionEs.respRecvd = FALSE;
33947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->sessionEs.rawRequest = NULL;
34047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->sessionEs.reqID = 0;
34147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_cond_init(&loc_eng_ni_data_p->sessionEs.tCond, NULL);
34247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_init(&loc_eng_ni_data_p->sessionEs.tLock, NULL);
34347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
34447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->session.respTimeLeft = 0;
34547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->session.respRecvd = FALSE;
34647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->session.rawRequest = NULL;
34747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        loc_eng_ni_data_p->session.reqID = 0;
34847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_cond_init(&loc_eng_ni_data_p->session.tCond, NULL);
34947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_init(&loc_eng_ni_data_p->session.tLock, NULL);
35034ee09551764b045fdc02df754157473125edf60Kevin Tang
35134ee09551764b045fdc02df754157473125edf60Kevin Tang        loc_eng_data.ni_notify_cb = callbacks->notify_cb;
35234ee09551764b045fdc02df754157473125edf60Kevin Tang        EXIT_LOG(%s, VOID_RET);
35334ee09551764b045fdc02df754157473125edf60Kevin Tang    }
35434ee09551764b045fdc02df754157473125edf60Kevin Tang}
35534ee09551764b045fdc02df754157473125edf60Kevin Tang
35634ee09551764b045fdc02df754157473125edf60Kevin Tang/*===========================================================================
35734ee09551764b045fdc02df754157473125edf60Kevin TangFUNCTION    loc_eng_ni_respond
35834ee09551764b045fdc02df754157473125edf60Kevin Tang
35934ee09551764b045fdc02df754157473125edf60Kevin TangDESCRIPTION
36034ee09551764b045fdc02df754157473125edf60Kevin Tang   This function receives user response from upper layer framework
36134ee09551764b045fdc02df754157473125edf60Kevin Tang
36234ee09551764b045fdc02df754157473125edf60Kevin TangDEPENDENCIES
36334ee09551764b045fdc02df754157473125edf60Kevin Tang   NONE
36434ee09551764b045fdc02df754157473125edf60Kevin Tang
36534ee09551764b045fdc02df754157473125edf60Kevin TangRETURN VALUE
36634ee09551764b045fdc02df754157473125edf60Kevin Tang   None
36734ee09551764b045fdc02df754157473125edf60Kevin Tang
36834ee09551764b045fdc02df754157473125edf60Kevin TangSIDE EFFECTS
36934ee09551764b045fdc02df754157473125edf60Kevin Tang   N/A
37034ee09551764b045fdc02df754157473125edf60Kevin Tang
37134ee09551764b045fdc02df754157473125edf60Kevin Tang===========================================================================*/
37234ee09551764b045fdc02df754157473125edf60Kevin Tangvoid loc_eng_ni_respond(loc_eng_data_s_type &loc_eng_data,
37334ee09551764b045fdc02df754157473125edf60Kevin Tang                        int notif_id, GpsUserResponseType user_response)
37434ee09551764b045fdc02df754157473125edf60Kevin Tang{
37534ee09551764b045fdc02df754157473125edf60Kevin Tang    ENTRY_LOG_CALLFLOW();
37634ee09551764b045fdc02df754157473125edf60Kevin Tang    loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
37747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    loc_eng_ni_session_s_type* pSession = NULL;
37834ee09551764b045fdc02df754157473125edf60Kevin Tang
37934ee09551764b045fdc02df754157473125edf60Kevin Tang    if (NULL == loc_eng_data.ni_notify_cb) {
38034ee09551764b045fdc02df754157473125edf60Kevin Tang        EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
38134ee09551764b045fdc02df754157473125edf60Kevin Tang        return;
38234ee09551764b045fdc02df754157473125edf60Kevin Tang    }
38334ee09551764b045fdc02df754157473125edf60Kevin Tang
38447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (notif_id == loc_eng_ni_data_p->sessionEs.reqID &&
38547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
38647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession = &loc_eng_ni_data_p->sessionEs;
38747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted
38847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        if (user_response == GPS_NI_RESPONSE_ACCEPT &&
38947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            NULL != loc_eng_ni_data_p->session.rawRequest) {
39047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock);
39147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                loc_eng_ni_data_p->session.resp = GPS_NI_RESPONSE_IGNORE;
39247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                loc_eng_ni_data_p->session.respRecvd = TRUE;
39347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                pthread_cond_signal(&loc_eng_ni_data_p->session.tCond);
39447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock);
39547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        }
39647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    } else if (notif_id == loc_eng_ni_data_p->session.reqID &&
39747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        NULL != loc_eng_ni_data_p->session.rawRequest) {
39847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession = &loc_eng_ni_data_p->session;
39947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    }
40047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
40147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    if (pSession) {
40234ee09551764b045fdc02df754157473125edf60Kevin Tang        LOC_LOGI("loc_eng_ni_respond: send user response %d for notif %d", user_response, notif_id);
40347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_lock(&pSession->tLock);
40447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->resp = user_response;
40547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pSession->respRecvd = TRUE;
40647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_cond_signal(&pSession->tCond);
40747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        pthread_mutex_unlock(&pSession->tLock);
40834ee09551764b045fdc02df754157473125edf60Kevin Tang    }
40934ee09551764b045fdc02df754157473125edf60Kevin Tang    else {
41047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        LOC_LOGE("loc_eng_ni_respond: notif_id %d not an active session", notif_id);
41134ee09551764b045fdc02df754157473125edf60Kevin Tang    }
41234ee09551764b045fdc02df754157473125edf60Kevin Tang
41334ee09551764b045fdc02df754157473125edf60Kevin Tang    EXIT_LOG(%s, VOID_RET);
41434ee09551764b045fdc02df754157473125edf60Kevin Tang}
415