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