1bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
2bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
3bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * Redistribution and use in source and binary forms, with or without
4bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * modification, are permitted provided that the following conditions are
5bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * met:
6bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *     * Redistributions of source code must retain the above copyright
7bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *       notice, this list of conditions and the following disclaimer.
8bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *     * Redistributions in binary form must reproduce the above
9bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *       copyright notice, this list of conditions and the following
10bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *       disclaimer in the documentation and/or other materials provided
11bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *       with the distribution.
12bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *     * Neither the name of The Linux Foundation, nor the names of its
13bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *       contributors may be used to endorse or promote products derived
14bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *       from this software without specific prior written permission.
15bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
16bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
28bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo */
29bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
30bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#define LOG_NDDEBUG 0
31bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#define LOG_TAG "LocSvc_eng"
32bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
33bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <stdio.h>
34bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <stdlib.h>
35bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <sys/time.h>
36bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <pthread.h>
37bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <errno.h>
38bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <string.h>
39bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <ctype.h>
40bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <unistd.h>
41bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <time.h>
42bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <MsgTask.h>
43bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
44bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include <loc_eng.h>
45bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
46bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include "log_util.h"
47bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo#include "platform_lib_includes.h"
48bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
49bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russousing namespace loc_core;
50bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
51bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/*=============================================================================
52bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
53bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *                             DATA DECLARATION
54bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
55bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *============================================================================*/
56bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
57bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/*=============================================================================
58bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
59bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *                             FUNCTION DECLARATIONS
60bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *
61bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo *============================================================================*/
62bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russostatic void* ni_thread_proc(void *args);
63bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
64bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russostruct LocEngInformNiResponse : public LocMsg {
65bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LocEngAdapter* mAdapter;
66bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    const GpsUserResponseType mResponse;
67bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    const void *mPayload;
68bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    inline LocEngInformNiResponse(LocEngAdapter* adapter,
69bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                                  GpsUserResponseType resp,
70bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                                  const void* data) :
71bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LocMsg(), mAdapter(adapter),
72bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        mResponse(resp), mPayload(data)
73bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
74bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        locallog();
75bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
76bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    inline ~LocEngInformNiResponse()
77bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
78bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // this is a bit weird since mPayload is not
79bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // allocated by this class.  But there is no better way.
80bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // mPayload actually won't be NULL here.
81bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        free((void*)mPayload);
82bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
83bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    inline virtual void proc() const
84bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
85bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        mAdapter->informNiResponse(mResponse, mPayload);
86bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
87bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    inline void locallog() const
88bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
89bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGV("LocEngInformNiResponse - "
90bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                 "response: %s\n  mPayload: %p",
91bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                 loc_get_ni_response_name(mResponse),
92bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                 mPayload);
93bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
94bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    inline virtual void log() const
95bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
96bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        locallog();
97bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
98bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo};
99bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
100bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/*===========================================================================
101bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
102bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoFUNCTION loc_eng_ni_request_handler
103bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
104bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoDESCRIPTION
105bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   Displays the NI request and awaits user input. If a previous request is
106bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   in session, it is ignored.
107bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
108bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoRETURN VALUE
109bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   none
110bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
111bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo===========================================================================*/
112bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russovoid loc_eng_ni_request_handler(loc_eng_data_s_type &loc_eng_data,
113bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                            const GpsNiNotification *notif,
114bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                            const void* passThrough)
115bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo{
116bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    ENTRY_LOG();
117bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    char lcs_addr[32]; // Decoded LCS address for UMTS CP NI
118bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
119bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    loc_eng_ni_session_s_type* pSession = NULL;
120bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
121bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL == loc_eng_data.ni_notify_cb) {
122bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
123bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        return;
124bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
125bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
126bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (notif->ni_type == GPS_NI_TYPE_EMERGENCY_SUPL) {
127bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
128bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGW("loc_eng_ni_request_handler, supl es NI in progress, new supl es NI ignored, type: %d",
129bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                     notif->ni_type);
130bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            if (NULL != passThrough) {
131bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                free((void*)passThrough);
132bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            }
133bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        } else {
134bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            pSession = &loc_eng_ni_data_p->sessionEs;
135bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
136bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    } else {
137bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (NULL != loc_eng_ni_data_p->session.rawRequest ||
138bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
139bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGW("loc_eng_ni_request_handler, supl NI in progress, new supl NI ignored, type: %d",
140bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                     notif->ni_type);
141bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            if (NULL != passThrough) {
142bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                free((void*)passThrough);
143bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            }
144bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        } else {
145bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            pSession = &loc_eng_ni_data_p->session;
146bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
147bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
148bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
149bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
150bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (pSession) {
151bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        /* Save request */
152bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->rawRequest = (void*)passThrough;
153bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->reqID = ++loc_eng_ni_data_p->reqIDCounter;
154bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->adapter = loc_eng_data.adapter;
155bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
156bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        /* Fill in notification */
157bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        ((GpsNiNotification*)notif)->notification_id = pSession->reqID;
158bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
159bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (notif->notify_flags == GPS_NI_PRIVACY_OVERRIDE)
160bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        {
161bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            loc_eng_mute_one_session(loc_eng_data);
162bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
163bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
164bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        /* Log requestor ID and text for debugging */
165bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGI("Notification: notif_type: %d, timeout: %d, default_resp: %d", notif->ni_type, notif->timeout, notif->default_response);
166bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGI("              requestor_id: %s (encoding: %d)", notif->requestor_id, notif->requestor_id_encoding);
167bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGI("              text: %s text (encoding: %d)", notif->text, notif->text_encoding);
168bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (notif->extras[0])
169bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        {
170bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGI("              extras: %s", notif->extras);
171bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
172bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
173bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        /* For robustness, spawn a thread at this point to timeout to clear up the notification status, even though
174bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo         * the OEM layer in java does not do so.
175bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo         **/
176bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->respTimeLeft = 5 + (notif->timeout != 0 ? notif->timeout : LOC_NI_NO_RESPONSE_TIME);
177bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGI("Automatically sends 'no response' in %d seconds (to clear status)\n", pSession->respTimeLeft);
178bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
179bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        int rc = 0;
180bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        rc = pthread_create(&pSession->thread, NULL, ni_thread_proc, pSession);
181bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (rc)
182bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        {
183bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGE("Loc NI thread is not created.\n");
184bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
185bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        rc = pthread_detach(pSession->thread);
186bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (rc)
187bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        {
188bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGE("Loc NI thread is not detached.\n");
189bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
190bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
191bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        CALLBACK_LOG_CALLFLOW("ni_notify_cb - id", %d, notif->notification_id);
192bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_data.ni_notify_cb((GpsNiNotification*)notif);
193bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
194bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    EXIT_LOG(%s, VOID_RET);
195bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo}
196bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
197bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/*===========================================================================
198bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
199bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoFUNCTION ni_thread_proc
200bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
201bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo===========================================================================*/
202bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russostatic void* ni_thread_proc(void *args)
203bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo{
204bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    ENTRY_LOG();
205bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
206bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    loc_eng_ni_session_s_type* pSession = (loc_eng_ni_session_s_type*)args;
207bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    int rc = 0;          /* return code from pthread calls */
208bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
209bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    struct timeval present_time;
210bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    struct timespec expire_time;
211bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
212bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LOC_LOGD("Starting Loc NI thread...\n");
213bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    pthread_mutex_lock(&pSession->tLock);
214bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    /* Calculate absolute expire time */
215bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    gettimeofday(&present_time, NULL);
216bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    expire_time.tv_sec  = present_time.tv_sec + pSession->respTimeLeft;
217bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    expire_time.tv_nsec = present_time.tv_usec * 1000;
218bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LOC_LOGD("ni_thread_proc-Time out set for abs time %ld with delay %d sec\n",
219bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo             (long) expire_time.tv_sec, pSession->respTimeLeft );
220bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
221bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    while (!pSession->respRecvd)
222bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    {
223bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        rc = pthread_cond_timedwait(&pSession->tCond,
224bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                                    &pSession->tLock,
225bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                                    &expire_time);
226bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (rc == ETIMEDOUT)
227bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        {
228bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            pSession->resp = GPS_NI_RESPONSE_NORESP;
229bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGD("ni_thread_proc-Thread time out after valting for specified time. Ret Val %d\n",rc );
230bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            break;
231bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
232bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
233bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LOC_LOGD("ni_thread_proc-Java layer has sent us a user response and return value from "
234bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo             "pthread_cond_timedwait = %d\n",rc );
235bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    pSession->respRecvd = FALSE; /* Reset the user response flag for the next session*/
236bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
237bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LOC_LOGD("pSession->resp is %d\n",pSession->resp);
238bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
239bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    // adding this check to support modem restart, in which case, we need the thread
240bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    // to exit without calling sending data. We made sure that rawRequest is NULL in
241bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    // loc_eng_ni_reset_on_engine_restart()
242bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LocEngAdapter* adapter = pSession->adapter;
243bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    LocEngInformNiResponse *msg = NULL;
244bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
245bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL != pSession->rawRequest) {
246bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (pSession->resp != GPS_NI_RESPONSE_IGNORE) {
247bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGD("pSession->resp != GPS_NI_RESPONSE_IGNORE \n");
248bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            msg = new LocEngInformNiResponse(adapter,
249bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                                             pSession->resp,
250bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                                             pSession->rawRequest);
251bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        } else {
252bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            LOC_LOGD("this is the ignore reply for SUPL ES\n");
253bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            free(pSession->rawRequest);
254bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
255bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->rawRequest = NULL;
256bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
257bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    pthread_mutex_unlock(&pSession->tLock);
258bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
259bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    pSession->respTimeLeft = 0;
260bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    pSession->reqID = 0;
261bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
262bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL != msg) {
263bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGD("ni_thread_proc: adapter->sendMsg(msg)\n");
264bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        adapter->sendMsg(msg);
265bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
266bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
267bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    EXIT_LOG(%s, VOID_RET);
268bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    return NULL;
269bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo}
270bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
271bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russovoid loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data)
272bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo{
273bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    ENTRY_LOG();
274bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
275bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
276bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL == loc_eng_data.ni_notify_cb) {
277bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
278bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        return;
279bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
280bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
281bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    // only if modem has requested but then died.
282bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
283bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        free(loc_eng_ni_data_p->sessionEs.rawRequest);
284bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->sessionEs.rawRequest = NULL;
285bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
286bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_lock(&loc_eng_ni_data_p->sessionEs.tLock);
287bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // the goal is to wake up ni_thread_proc
288bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // and let it exit.
289bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->sessionEs.respRecvd = TRUE;
290bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_cond_signal(&loc_eng_ni_data_p->sessionEs.tCond);
291bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_unlock(&loc_eng_ni_data_p->sessionEs.tLock);
292bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
293bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
294bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL != loc_eng_ni_data_p->session.rawRequest) {
295bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        free(loc_eng_ni_data_p->session.rawRequest);
296bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->session.rawRequest = NULL;
297bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
298bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock);
299bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // the goal is to wake up ni_thread_proc
300bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // and let it exit.
301bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->session.respRecvd = TRUE;
302bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_cond_signal(&loc_eng_ni_data_p->session.tCond);
303bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock);
304bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
305bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
306bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    EXIT_LOG(%s, VOID_RET);
307bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo}
308bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
309bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/*===========================================================================
310bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoFUNCTION    loc_eng_ni_init
311bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
312bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoDESCRIPTION
313bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   This function initializes the NI interface
314bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
315bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoDEPENDENCIES
316bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   NONE
317bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
318bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoRETURN VALUE
319bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   None
320bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
321bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoSIDE EFFECTS
322bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   N/A
323bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
324bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo===========================================================================*/
325bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russovoid loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data, GpsNiExtCallbacks *callbacks)
326bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo{
327bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    ENTRY_LOG_CALLFLOW();
328bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
329bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if(callbacks == NULL)
330bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, "loc_eng_ni_init: failed, cb is NULL");
331bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    else if (NULL == callbacks->notify_cb) {
332bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, "loc_eng_ni_init: failed, no cb.");
333bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    } else if (NULL != loc_eng_data.ni_notify_cb) {
334bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, "loc_eng_ni_init: already inited.");
335bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    } else {
336bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
337bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->sessionEs.respTimeLeft = 0;
338bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->sessionEs.respRecvd = FALSE;
339bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->sessionEs.rawRequest = NULL;
340bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->sessionEs.reqID = 0;
341bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_cond_init(&loc_eng_ni_data_p->sessionEs.tCond, NULL);
342bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_init(&loc_eng_ni_data_p->sessionEs.tLock, NULL);
343bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
344bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->session.respTimeLeft = 0;
345bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->session.respRecvd = FALSE;
346bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->session.rawRequest = NULL;
347bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_ni_data_p->session.reqID = 0;
348bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_cond_init(&loc_eng_ni_data_p->session.tCond, NULL);
349bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_init(&loc_eng_ni_data_p->session.tLock, NULL);
350bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
351bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        loc_eng_data.ni_notify_cb = callbacks->notify_cb;
352bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, VOID_RET);
353bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
354bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo}
355bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
356bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo/*===========================================================================
357bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoFUNCTION    loc_eng_ni_respond
358bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
359bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoDESCRIPTION
360bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   This function receives user response from upper layer framework
361bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
362bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoDEPENDENCIES
363bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   NONE
364bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
365bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoRETURN VALUE
366bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   None
367bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
368bfff6343845ad9ff062c5fd97bb3b9be1053340eDante RussoSIDE EFFECTS
369bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo   N/A
370bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
371bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo===========================================================================*/
372bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russovoid loc_eng_ni_respond(loc_eng_data_s_type &loc_eng_data,
373bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                        int notif_id, GpsUserResponseType user_response)
374bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo{
375bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    ENTRY_LOG_CALLFLOW();
376bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data;
377bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    loc_eng_ni_session_s_type* pSession = NULL;
378bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
379bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (NULL == loc_eng_data.ni_notify_cb) {
380bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet.");
381bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        return;
382bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
383bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
384bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (notif_id == loc_eng_ni_data_p->sessionEs.reqID &&
385bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        NULL != loc_eng_ni_data_p->sessionEs.rawRequest) {
386bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession = &loc_eng_ni_data_p->sessionEs;
387bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted
388bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        if (user_response == GPS_NI_RESPONSE_ACCEPT &&
389bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo            NULL != loc_eng_ni_data_p->session.rawRequest) {
390bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock);
391bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                loc_eng_ni_data_p->session.resp = GPS_NI_RESPONSE_IGNORE;
392bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                loc_eng_ni_data_p->session.respRecvd = TRUE;
393bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                pthread_cond_signal(&loc_eng_ni_data_p->session.tCond);
394bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo                pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock);
395bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        }
396bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    } else if (notif_id == loc_eng_ni_data_p->session.reqID &&
397bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        NULL != loc_eng_ni_data_p->session.rawRequest) {
398bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession = &loc_eng_ni_data_p->session;
399bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
400bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
401bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    if (pSession) {
402bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGI("loc_eng_ni_respond: send user response %d for notif %d", user_response, notif_id);
403bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_lock(&pSession->tLock);
404bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->resp = user_response;
405bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pSession->respRecvd = TRUE;
406bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_cond_signal(&pSession->tCond);
407bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        pthread_mutex_unlock(&pSession->tLock);
408bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
409bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    else {
410bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo        LOC_LOGE("loc_eng_ni_respond: notif_id %d not an active session", notif_id);
411bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    }
412bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo
413bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo    EXIT_LOG(%s, VOID_RET);
414bfff6343845ad9ff062c5fd97bb3b9be1053340eDante Russo}
415