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 0; 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