Home | History | Annotate | Download | only in libloc_api_50001
      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 
     47 static int loc_api_server_msgqid;
     48 static int loc_api_resp_msgqid;
     49 static int quipc_msgqid;
     50 static int msapm_msgqid;
     51 static int msapu_msgqid;
     52 
     53 static const char * global_loc_api_q_path = GPSONE_LOC_API_Q_PATH;
     54 static const char * global_loc_api_resp_q_path = GPSONE_LOC_API_RESP_Q_PATH;
     55 static const char * global_quipc_ctrl_q_path = QUIPC_CTRL_Q_PATH;
     56 static const char * global_msapm_ctrl_q_path = MSAPM_CTRL_Q_PATH;
     57 static const char * global_msapu_ctrl_q_path = MSAPU_CTRL_Q_PATH;
     58 
     59 static 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 
    112 static int loc_api_server_proc_pre(void *context)
    113 {
    114     return 0;
    115 }
    116 
    117 static 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 
    167 static 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 
    178 static 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 
    187 static struct loc_eng_dmn_conn_thelper thelper;
    188 
    189 int 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 
    213 int 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 
    220 int loc_eng_dmn_conn_loc_api_server_join(void)
    221 {
    222     loc_eng_dmn_conn_join_thelper(&thelper);
    223     return 0;
    224 }
    225 
    226 int 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