1/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation, nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <linux/stat.h>
33#include <fcntl.h>
34#include <linux/types.h>
35#include <unistd.h>
36#include <errno.h>
37#include <grp.h>
38#include <sys/stat.h>
39
40#include "log_util.h"
41#include "platform_lib_includes.h"
42#include "loc_eng_dmn_conn_glue_msg.h"
43#include "loc_eng_dmn_conn_handler.h"
44#include "loc_eng_dmn_conn.h"
45#include "loc_eng_msg.h"
46
47static int loc_api_server_msgqid;
48static int loc_api_resp_msgqid;
49static int quipc_msgqid;
50static int msapm_msgqid;
51static int msapu_msgqid;
52
53static const char * global_loc_api_q_path = GPSONE_LOC_API_Q_PATH;
54static const char * global_loc_api_resp_q_path = GPSONE_LOC_API_RESP_Q_PATH;
55static const char * global_quipc_ctrl_q_path = QUIPC_CTRL_Q_PATH;
56static const char * global_msapm_ctrl_q_path = MSAPM_CTRL_Q_PATH;
57static const char * global_msapu_ctrl_q_path = MSAPU_CTRL_Q_PATH;
58
59static int loc_api_server_proc_init(void *context)
60{
61    loc_api_server_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_q_path, O_RDWR);
62    //change mode/group for the global_loc_api_q_path pipe
63    int result = chmod (global_loc_api_q_path, 0660);
64    if (result != 0)
65    {
66        LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_q_path, strerror(errno));
67    }
68
69    struct group * gps_group = getgrnam("gps");
70    if (gps_group != NULL)
71    {
72       result = chown (global_loc_api_q_path, -1, gps_group->gr_gid);
73       if (result != 0)
74       {
75          LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n",
76                   global_loc_api_q_path, gps_group->gr_gid, result, strerror(errno));
77       }
78    }
79    else
80    {
81       LOC_LOGE("getgrnam for gps failed, error code = %d\n",  errno);
82    }
83
84    loc_api_resp_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_resp_q_path, O_RDWR);
85
86    //change mode/group for the global_loc_api_resp_q_path pipe
87    result = chmod (global_loc_api_resp_q_path, 0660);
88    if (result != 0)
89    {
90        LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_resp_q_path, strerror(errno));
91    }
92
93    if (gps_group != NULL)
94    {
95       result = chown (global_loc_api_resp_q_path, -1, gps_group->gr_gid);
96       if (result != 0)
97       {
98          LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n",
99                   global_loc_api_resp_q_path,
100                   gps_group->gr_gid, result, strerror(errno));
101       }
102    }
103
104    quipc_msgqid = loc_eng_dmn_conn_glue_msgget(global_quipc_ctrl_q_path, O_RDWR);
105    msapm_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapm_ctrl_q_path , O_RDWR);
106    msapu_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapu_ctrl_q_path , O_RDWR);
107
108    LOC_LOGD("%s:%d] loc_api_server_msgqid = %d\n", __func__, __LINE__, loc_api_server_msgqid);
109    return 0;
110}
111
112static int loc_api_server_proc_pre(void *context)
113{
114    return 0;
115}
116
117static int loc_api_server_proc(void *context)
118{
119    int length, sz;
120    int result = 0;
121    static int cnt = 0;
122    struct ctrl_msgbuf * p_cmsgbuf;
123    struct ctrl_msgbuf cmsg_resp;
124
125    sz = sizeof(struct ctrl_msgbuf) + 256;
126    p_cmsgbuf = (struct ctrl_msgbuf *) malloc(sz);
127
128    if (!p_cmsgbuf) {
129        LOC_LOGE("%s:%d] Out of memory\n", __func__, __LINE__);
130        return -1;
131    }
132
133    cnt ++;
134    LOC_LOGD("%s:%d] %d listening on %s...\n", __func__, __LINE__, cnt, (char *) context);
135    length = loc_eng_dmn_conn_glue_msgrcv(loc_api_server_msgqid, p_cmsgbuf, sz);
136    if (length <= 0) {
137        free(p_cmsgbuf);
138        LOC_LOGE("%s:%d] fail receiving msg from gpsone_daemon, retry later\n", __func__, __LINE__);
139        usleep(1000);
140        return -1;
141    }
142
143    LOC_LOGD("%s:%d] received ctrl_type = %d\n", __func__, __LINE__, p_cmsgbuf->ctrl_type);
144    switch(p_cmsgbuf->ctrl_type) {
145        case GPSONE_LOC_API_IF_REQUEST:
146            result = loc_eng_dmn_conn_loc_api_server_if_request_handler(p_cmsgbuf, length);
147            break;
148
149        case GPSONE_LOC_API_IF_RELEASE:
150            result = loc_eng_dmn_conn_loc_api_server_if_release_handler(p_cmsgbuf, length);
151            break;
152
153        case GPSONE_UNBLOCK:
154            LOC_LOGD("%s:%d] GPSONE_UNBLOCK\n", __func__, __LINE__);
155            break;
156
157        default:
158            LOC_LOGE("%s:%d] unsupported ctrl_type = %d\n",
159                __func__, __LINE__, p_cmsgbuf->ctrl_type);
160            break;
161    }
162
163    free(p_cmsgbuf);
164    return 0;
165}
166
167static int loc_api_server_proc_post(void *context)
168{
169    LOC_LOGD("%s:%d]\n", __func__, __LINE__);
170    loc_eng_dmn_conn_glue_msgremove( global_loc_api_q_path, loc_api_server_msgqid);
171    loc_eng_dmn_conn_glue_msgremove( global_loc_api_resp_q_path, loc_api_resp_msgqid);
172    loc_eng_dmn_conn_glue_msgremove( global_quipc_ctrl_q_path, quipc_msgqid);
173    loc_eng_dmn_conn_glue_msgremove( global_msapm_ctrl_q_path, msapm_msgqid);
174    loc_eng_dmn_conn_glue_msgremove( global_msapu_ctrl_q_path, msapu_msgqid);
175    return 0;
176}
177
178static int loc_eng_dmn_conn_unblock_proc(void)
179{
180    struct ctrl_msgbuf cmsgbuf;
181    cmsgbuf.ctrl_type = GPSONE_UNBLOCK;
182    LOC_LOGD("%s:%d]\n", __func__, __LINE__);
183    loc_eng_dmn_conn_glue_msgsnd(loc_api_server_msgqid, & cmsgbuf, sizeof(cmsgbuf));
184    return 0;
185}
186
187static struct loc_eng_dmn_conn_thelper thelper;
188
189int loc_eng_dmn_conn_loc_api_server_launch(thelper_create_thread   create_thread_cb,
190    const char * loc_api_q_path, const char * resp_q_path, void *agps_handle)
191{
192    int result;
193
194    loc_api_handle = agps_handle;
195
196    if (loc_api_q_path) global_loc_api_q_path = loc_api_q_path;
197    if (resp_q_path)    global_loc_api_resp_q_path = resp_q_path;
198
199    result = loc_eng_dmn_conn_launch_thelper( &thelper,
200        loc_api_server_proc_init,
201        loc_api_server_proc_pre,
202        loc_api_server_proc,
203        loc_api_server_proc_post,
204        create_thread_cb,
205        (char *) global_loc_api_q_path);
206    if (result != 0) {
207        LOC_LOGE("%s:%d]\n", __func__, __LINE__);
208        return -1;
209    }
210    return 0;
211}
212
213int loc_eng_dmn_conn_loc_api_server_unblock(void)
214{
215    loc_eng_dmn_conn_unblock_thelper(&thelper);
216    loc_eng_dmn_conn_unblock_proc();
217    return 0;
218}
219
220int loc_eng_dmn_conn_loc_api_server_join(void)
221{
222    loc_eng_dmn_conn_join_thelper(&thelper);
223    return 0;
224}
225
226int loc_eng_dmn_conn_loc_api_server_data_conn(int sender_id, int status) {
227  struct ctrl_msgbuf cmsgbuf;
228  LOC_LOGD("%s:%d] quipc_msgqid = %d\n", __func__, __LINE__, quipc_msgqid);
229  cmsgbuf.ctrl_type = GPSONE_LOC_API_RESPONSE;
230  cmsgbuf.cmsg.cmsg_response.result = status;
231  switch (sender_id) {
232    case LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC: {
233      LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC", __func__, __LINE__);
234      if (loc_eng_dmn_conn_glue_msgsnd(quipc_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
235        LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
236        return -1;
237      }
238      break;
239    }
240    case LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM: {
241      LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM", __func__, __LINE__);
242      if (loc_eng_dmn_conn_glue_msgsnd(msapm_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
243        LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
244        return -1;
245      }
246      break;
247    }
248    case LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU: {
249      LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU", __func__, __LINE__);
250      if (loc_eng_dmn_conn_glue_msgsnd(msapu_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
251        LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
252        return -1;
253      }
254      break;
255    }
256    case LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON: {
257      LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON", __func__, __LINE__);
258      if (loc_eng_dmn_conn_glue_msgsnd(loc_api_resp_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) {
259        LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__);
260        return -1;
261      }
262      break;
263    }
264    default: {
265      LOC_LOGD("%s:%d] invalid sender ID!", __func__, __LINE__);
266    }
267  }
268  return 0;
269}
270
271