pwr: Refactor code, check for NULL pointers and prevent memory leaks
[samsung-ril.git] / pwr.c
1 /*
2  * This file is part of Samsung-RIL.
3  *
4  * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5  * Copyright (C) 2011-2012 Paul Kocialkowski <contact@paulk.fr>
6  *
7  * Samsung-RIL is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Samsung-RIL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Samsung-RIL.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #define LOG_TAG "RIL-PWR"
23 #include <utils/Log.h>
24
25 #include "samsung-ril.h"
26 #include "util.h"
27
28 /*
29  * Modem lets us know it's powered on. Though, it's still in LPM and should
30  * be considered as OFF. This request is used as a first indication that
31  * we can communicate with the modem, so unlock RIL start from here.
32  */
33
34 void ipc_pwr_phone_pwr_up(void)
35 {
36         ril_data.state.radio_state = RADIO_STATE_OFF;
37         ril_data.state.power_state = IPC_PWR_PHONE_STATE_LPM;
38
39         RIL_START_UNLOCK();
40 }
41
42 void ipc_pwr_phone_reset(void)
43 {
44         ril_data.state.radio_state = RADIO_STATE_OFF;
45         ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
46 }
47
48 void ipc_pwr_phone_state(struct ipc_message_info *info)
49 {
50         unsigned char state;
51
52         if (info == NULL || info->data == NULL || info->length < sizeof(unsigned char))
53                 return;
54
55         state = *((unsigned char *) info->data);
56
57         switch (state) {
58                 case IPC_PWR_R(IPC_PWR_PHONE_STATE_LPM):
59                         LOGD("Got power to LPM");
60
61                         if (ril_data.tokens.radio_power != (RIL_Token) 0x00) {
62                                 ril_request_complete(ril_data.tokens.radio_power, RIL_E_SUCCESS, NULL, 0);
63                                 ril_data.tokens.radio_power = (RIL_Token) 0x00;
64                         }
65
66                         ril_data.state.radio_state = RADIO_STATE_OFF;
67                         ril_data.state.power_state = IPC_PWR_PHONE_STATE_LPM;
68                         ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
69                         break;
70                 case IPC_PWR_R(IPC_PWR_PHONE_STATE_NORMAL):
71                         LOGD("Got power to NORMAL");
72
73                         if (ril_data.tokens.radio_power != (RIL_Token) 0x00) {
74                                 ril_request_complete(ril_data.tokens.radio_power, RIL_E_SUCCESS, NULL, 0);
75                                 ril_data.tokens.radio_power = (RIL_Token) 0x00;
76                         }
77
78                         ril_data.state.radio_state = RADIO_STATE_SIM_NOT_READY;
79                         ril_data.state.power_state = IPC_PWR_PHONE_STATE_NORMAL;
80                         ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
81                         break;
82         }
83
84         ril_tokens_check();
85 }
86
87 void ril_request_radio_power(RIL_Token t, void *data, int length)
88 {
89         int power_state;
90         unsigned short power_data;
91
92         if (data == NULL || length < (int) sizeof(int))
93                 return;
94
95         power_state = *((int *) data);
96
97         LOGD("requested power_state is %d", power_state);
98
99         if (power_state > 0) {
100                 LOGD("Request power to NORMAL");
101                 power_data = IPC_PWR_PHONE_STATE_NORMAL;
102
103                 ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_PWR_PHONE_STATE);
104                 ipc_fmt_send(IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), ril_request_get_id(t));
105
106                 ril_data.tokens.radio_power = t;
107         } else {
108                 LOGD("Request power to LPM");
109                 power_data = IPC_PWR_PHONE_STATE_LPM;
110
111                 ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_PWR_PHONE_STATE);
112                 ipc_fmt_send(IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), ril_request_get_id(t));
113
114                 ril_data.tokens.radio_power = t;
115         }
116 }