diff options
author | PaulK <contact@paulk.fr> | 2011-12-21 21:54:03 +0100 |
---|---|---|
committer | PaulK <contact@paulk.fr> | 2011-12-21 21:54:03 +0100 |
commit | 0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752 (patch) | |
tree | dff5b107e7c51dcbb71d636fd6189d3570881a39 | |
parent | cb295e0a15c8bc5087a542f25bc369aecbecde80 (diff) | |
download | hardware_ril_samsung-ril-0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752.zip hardware_ril_samsung-ril-0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752.tar.gz hardware_ril_samsung-ril-0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752.tar.bz2 |
RIL rework: multi-client, more stable, added GPLv3 copyright notice
-rw-r--r-- | Android.mk | 70 | ||||
-rw-r--r-- | call.c | 205 | ||||
-rw-r--r-- | client.c | 187 | ||||
-rw-r--r-- | disp.c | 37 | ||||
-rw-r--r-- | include/samsung-ril-socket.h | 62 | ||||
-rw-r--r-- | ipc.c | 216 | ||||
-rw-r--r-- | ipc.h | 45 | ||||
-rw-r--r-- | misc.c | 149 | ||||
-rw-r--r-- | net.c | 246 | ||||
-rw-r--r-- | pwr.c | 55 | ||||
-rw-r--r-- | samsung-ril.c | 696 | ||||
-rw-r--r-- | samsung-ril.h | 288 | ||||
-rw-r--r-- | sat.c | 61 | ||||
-rw-r--r-- | sim.c | 180 | ||||
-rw-r--r-- | sms.c | 228 | ||||
-rw-r--r-- | snd.c | 34 | ||||
-rw-r--r-- | socket.c | 148 | ||||
-rw-r--r-- | socket.h | 24 | ||||
-rw-r--r-- | srs.c | 291 | ||||
-rw-r--r-- | srs.h | 50 | ||||
-rw-r--r-- | util.c | 74 | ||||
-rw-r--r-- | util.h | 26 |
22 files changed, 2206 insertions, 1166 deletions
@@ -1,23 +1,43 @@ -# Copyright 2006 The Android Open Source Project +# This file is part of samsung-ril. +# +# Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> +# Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> +# +# samsung-ril is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# samsung-ril is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. +# LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ - call.c \ - samsung-ril.c \ - misc.c \ - net.c \ - sat.c \ - sim.c \ - sms.c \ - util.c \ - pwr.c \ - disp.c \ - socket.c + samsung-ril.c \ + client.c \ + ipc.c \ + srs.c \ + util.c \ + pwr.c \ + disp.c \ + misc.c \ + sat.c \ + sim.c \ + net.c \ + sms.c \ + call.c \ + snd.c LOCAL_SHARED_LIBRARIES := \ - libcutils libutils libril + libcutils libutils libril LOCAL_STATIC_LIBRARIES := libsamsung-ipc @@ -40,17 +60,17 @@ LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false ifeq (foo,foo) - #build shared library - LOCAL_SHARED_LIBRARIES += \ - libcutils libutils - LOCAL_LDLIBS += -lpthread - LOCAL_CFLAGS += -DRIL_SHLIB -DDEVICE_H1 - LOCAL_MODULE:= libsamsung-ril - include $(BUILD_SHARED_LIBRARY) + # build shared library + LOCAL_SHARED_LIBRARIES += \ + libcutils libutils + LOCAL_LDLIBS += -lpthread + LOCAL_CFLAGS += -DRIL_SHLIB + LOCAL_MODULE:= libsamsung-ril + include $(BUILD_SHARED_LIBRARY) else - #build executable - LOCAL_SHARED_LIBRARIES += \ - libril - LOCAL_MODULE:= samsung-ril - include $(BUILD_EXECUTABLE) + # build executable + LOCAL_SHARED_LIBRARIES += \ + libril + LOCAL_MODULE:= samsung-ril + include $(BUILD_EXECUTABLE) endif @@ -1,11 +1,100 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-CALL" #include <utils/Log.h> #include "samsung-ril.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; +/** + * In: RIL_UNSOL_CALL_RING + * Ring indication for an incoming call (eg, RING or CRING event). + */ +void ipc_call_incoming(struct ipc_message_info *info) +{ + RIL_onUnsolicitedResponse(RIL_UNSOL_CALL_RING, NULL, 0); + + /* FIXME: Do we really need to send this? */ + RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); +} + +/** + * In: IPC_CALL_STATUS + * Indicates that a call's status has changed + * + * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED + * Indicate when call state has changed + */ +void ipc_call_status(struct ipc_message_info *info) +{ + RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); +} + +/** + * In: RIL_REQUEST_DIAL + * Initiate voice call + * + * Out: IPC_CALL_OUTGOING + */ +void ril_request_dial(RIL_Token t, void *data, size_t datalen) +{ + const RIL_Dial *dial = (const RIL_Dial*)data; + struct ipc_call_outgoing call; + int clir; + + if(strlen(dial->address) > sizeof(call.number)) { + printf("Outgoing call number too long\n"); + return; + } + + /* FIXME: separate method? */ + switch(dial->clir) { + case 0: + clir = IPC_CALL_IDENTITY_DEFAULT; + break; + case 1: + clir = IPC_CALL_IDENTITY_SHOW; + break; + case 2: + clir = IPC_CALL_IDENTITY_HIDE; + break; + default: + clir = IPC_CALL_IDENTITY_DEFAULT; + break; + } + + memset(&call, 0x00, sizeof(call)); + + call.type = IPC_CALL_TYPE_VOICE; + call.identity = clir; + call.prefix = IPC_CALL_PREFIX_NONE; + + call.length = strlen(dial->address); + memcpy(call.number, dial->address, strlen(dial->address)); + + ipc_fmt_send(IPC_CALL_OUTGOING, IPC_TYPE_EXEC, (unsigned char *) &call, sizeof(call), reqGetId(t)); + + /* FIXME: This should actually be sent based on the response from baseband */ + RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); +} unsigned char call_list_entry_state_ipc2ril(unsigned char call_state) { @@ -35,9 +124,9 @@ unsigned char call_list_entry_state_ipc2ril(unsigned char call_state) * Out: IPC_CALL_LIST GET * Requests a list of active calls */ -void requestGetCurrentCalls(RIL_Token t) +void ril_request_get_current_calls(RIL_Token t) { - ipc_client_send_get(IPC_CALL_LIST, getRequestId(t)); + ipc_fmt_send_get(IPC_CALL_LIST, reqGetId(t)); } /** @@ -47,25 +136,25 @@ void requestGetCurrentCalls(RIL_Token t) * Out: RIL_REQUEST_GET_CURRENT_CALLS * Requests current call list */ -void respondCallList(RIL_Token t, void *data, int length) +void ipc_call_list(struct ipc_message_info *info) { struct ipc_call_list_entry *entry; unsigned char num_entries; char *number, *number_ril; int i; - num_entries = *((unsigned char*)data); - entry = (struct ipc_call_list_entry*)((char*)data+1); + num_entries = *((unsigned char *) info->data); + entry = (struct ipc_call_list_entry *) ((char *) info->data + 1); - RIL_Call **calls = (RIL_Call**)malloc(num_entries * sizeof(RIL_Call*)); + RIL_Call **calls = (RIL_Call **) malloc(num_entries * sizeof(RIL_Call *)); for(i = 0; i < num_entries; i++) { - RIL_Call *call = (RIL_Call*)malloc(sizeof(RIL_Call)); + RIL_Call *call = (RIL_Call *) malloc(sizeof(RIL_Call)); /* Number is located after call list entry */ - number = ((char*)entry) + sizeof(*entry); + number = ((char *) entry) + sizeof(*entry); - number_ril = (char*)malloc(entry->number_len + 1); + number_ril = (char *) malloc(entry->number_len + 1); memset(number_ril, 0, (entry->number_len + 1)); memcpy(number_ril, number, entry->number_len); @@ -86,10 +175,10 @@ void respondCallList(RIL_Token t, void *data, int length) calls[i] = call; /* Next entry after current number */ - entry = (struct ipc_call_list_entry*)(number + entry->number_len); + entry = (struct ipc_call_list_entry *) (number + entry->number_len); } - RIL_onRequestComplete(t, RIL_E_SUCCESS, calls, (num_entries * sizeof(RIL_Call*))); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, calls, (num_entries * sizeof(RIL_Call *))); for(i = 0; i < num_entries; i++) { free(calls[i]); @@ -104,9 +193,9 @@ void respondCallList(RIL_Token t, void *data, int length) * * Out: IPC_CALL_RELEASE EXEC */ -void requestHangup(RIL_Token t) +void ril_request_hangup(RIL_Token t) { - ipc_client_send_exec(IPC_CALL_RELEASE, getRequestId(t)); + ipc_fmt_send_exec(IPC_CALL_RELEASE, reqGetId(t)); /* FIXME: This should actually be sent based on the response from baseband */ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); @@ -121,9 +210,9 @@ void requestHangup(RIL_Token t) * * Out: IPC_CALL_ANSWER */ -void requestAnswer(RIL_Token t) +void ril_request_answer(RIL_Token t) { - ipc_client_send_exec(IPC_CALL_ANSWER, getRequestId(t)); + ipc_fmt_send_exec(IPC_CALL_ANSWER, reqGetId(t)); /* FIXME: This should actually be sent based on the response from baseband */ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); @@ -132,79 +221,7 @@ void requestAnswer(RIL_Token t) RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); } -/** - * In: RIL_REQUEST_DIAL - * Initiate voice call - * - * Out: IPC_CALL_OUTGOING - */ -void requestDial(RIL_Token t, void *data, size_t datalen) -{ - const RIL_Dial *dial = (const RIL_Dial*)data; - struct ipc_call_outgoing call; - int clir; - - if(strlen(dial->address) > sizeof(call.number)) { - printf("Outgoing call number too long\n"); - return; - } - - /* FIXME: separate method? */ - switch(dial->clir) { - case 0: - clir = IPC_CALL_IDENTITY_DEFAULT; - break; - case 1: - clir = IPC_CALL_IDENTITY_SHOW; - break; - case 2: - clir = IPC_CALL_IDENTITY_HIDE; - break; - default: - clir = IPC_CALL_IDENTITY_DEFAULT; - break; - } - - memset(&call, 0x00, sizeof(call)); - - call.type = IPC_CALL_TYPE_VOICE; - call.identity = clir; - call.prefix = IPC_CALL_PREFIX_NONE; - - call.length = strlen(dial->address); - memcpy(call.number, dial->address, strlen(dial->address)); - - ipc_client_send(ipc_client, IPC_CALL_OUTGOING, IPC_TYPE_EXEC, (unsigned char*)&call, sizeof(call), getRequestId(t)); - - /* FIXME: This should actually be sent based on the response from baseband */ - RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -/** - * In: RIL_UNSOL_CALL_RING - * Ring indication for an incoming call (eg, RING or CRING event). - */ -void respondCallIncoming(RIL_Token t, void *data, int length) -{ - RIL_onUnsolicitedResponse(RIL_UNSOL_CALL_RING, NULL, 0); - - /* FIXME: Do we really need to send this? */ - RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); -} - -/** - * In: IPC_CALL_STATUS - * Indicates that a call's status has changed - * - * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED - * Indicate when call state has changed - */ -void respondCallStatus(RIL_Token t, void *data, int length) -{ - RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); -} - -void requestDtmfStart(RIL_Token t, void *data, int length) +void ril_request_dtmf_start(RIL_Token t, void *data, int length) { //TODO: Check if there is already a DTMF going on and cancel it if so @@ -212,18 +229,18 @@ void requestDtmfStart(RIL_Token t, void *data, int length) cont_dtmf.state = IPC_CALL_DTMF_STATE_START; cont_dtmf.tone = ((char *)data)[0]; - ipc_client_send(ipc_client, IPC_CALL_CONT_DTMF, IPC_TYPE_SET, (unsigned char*)&cont_dtmf, sizeof(cont_dtmf), getRequestId(t)); + ipc_fmt_send(IPC_CALL_CONT_DTMF, IPC_TYPE_SET, (unsigned char*)&cont_dtmf, sizeof(cont_dtmf), reqGetId(t)); RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); } -void requestDtmfStop(RIL_Token t) +void ril_request_dtmf_stop(RIL_Token t) { struct ipc_call_cont_dtmf cont_dtmf; cont_dtmf.state = IPC_CALL_DTMF_STATE_STOP; cont_dtmf.tone = 0; - ipc_client_send(ipc_client, IPC_CALL_CONT_DTMF, IPC_TYPE_SET, (unsigned char*)&cont_dtmf, sizeof(cont_dtmf), getRequestId(t)); + ipc_fmt_send(IPC_CALL_CONT_DTMF, IPC_TYPE_SET, (unsigned char*)&cont_dtmf, sizeof(cont_dtmf), reqGetId(t)); RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); } diff --git a/client.c b/client.c new file mode 100644 index 0000000..84cbbd5 --- /dev/null +++ b/client.c @@ -0,0 +1,187 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <pthread.h> + +#define LOG_TAG "RIL" +#include <utils/Log.h> + +#include "samsung-ril.h" + +/** + * RIL client functions + */ + +struct ril_client *ril_client_new(struct ril_client_funcs *client_funcs) +{ + struct ril_client *ril_client; + int rc; + + ril_client = malloc(sizeof(struct ril_client)); + memset(ril_client, 0, sizeof(struct ril_client)); + + if(client_funcs->create) + ril_client->create = client_funcs->create; + + if(client_funcs->destroy) + ril_client->destroy = client_funcs->destroy; + + if(client_funcs->read_loop) + ril_client->read_loop = client_funcs->read_loop; + + pthread_mutex_init(&(ril_client->mutex), NULL); + + return ril_client; +} + +int ril_client_free(struct ril_client *client) +{ + pthread_mutex_destroy(&(client->mutex)); + + free(client); + client = NULL; + + return 0; +} + +int ril_client_create(struct ril_client *client) +{ + int rc; + int c; + + for(c = 5 ; c > 0 ; c--) { + LOGD("Creating RIL client inners, try #%d", 6-c); + + rc = client->create(client); + + if(rc < 0) + LOGD("RIL client inners creation failed!"); + else + break; + } + + if(c == 0) { + client->state = RIL_CLIENT_ERROR; + return -1; + } + + client->state = RIL_CLIENT_CREATED; + + return 0; +} + +int ril_client_destroy(struct ril_client *client) +{ + int rc; + int c; + + for(c = 5 ; c > 0 ; c--) { + LOGD("Destroying RIL client inners, try #%d", 6-c); + + rc = client->destroy(client); + + if(rc < 0) + LOGD("RIL client inners destroying failed!"); + else + break; + } + + if(c == 0) { + client->state = RIL_CLIENT_ERROR; + return -1; + } + + client->state = RIL_CLIENT_DESTROYED; + + return 0; +} + +void *ril_client_thread(void *data) +{ + struct ril_client *client; + int rc; + int c; + + if(data == NULL) { + LOGE("Data passed to thread is NULL!"); + + return 0; + } + + client = (struct ipc_client *) data; + + for(c = 5 ; c > 0 ; c--) { + client->state = RIL_CLIENT_READY; + + rc = client->read_loop(client); + + if(rc < 0) { + client->state = RIL_CLIENT_ERROR; + + LOGE("There was an error with the read loop! Trying to destroy and recreate client object"); + + ril_client_destroy(client); + ril_client_create(client); + + continue; + } else { + client->state = RIL_CLIENT_CREATED; + + LOGD("read loop ended with no error!"); + break; + } + } + + if(c == 0) { + LOGE("FATAL: Main loop failed too many times."); + } + + // We are destroying everything here + + rc = ril_client_destroy(client); + if(rc < 0) { + LOGE("RIL client destroy failed!"); + } + + rc = ril_client_free(client); + if(rc < 0) { + LOGE("RIL client free failed!"); + } + + return 0; +} + +int ril_client_thread_start(struct ril_client *client) +{ + pthread_attr_t attr; + int rc; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + rc = pthread_create(&(client->thread), &attr, ril_client_thread, (void *) client); + + if(rc != 0) { + LOGE("pthread creation failed"); + return -1; + } + + return 0; +} @@ -1,21 +1,38 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-DISP" #include <utils/Log.h> #include "samsung-ril.h" #include "util.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; - -void respondIconSignalStrength(RIL_Token t, void *data, int length) +void ipc_disp_icon_info(struct ipc_message_info *info) { - struct ipc_disp_icon_info *signal_info = (struct ipc_disp_icon_info*)data; + struct ipc_disp_icon_info *signal_info = (struct ipc_disp_icon_info *) info->data; RIL_SignalStrength ss; int rssi; /* Don't consider this if modem isn't in normal power mode. */ - if(radio.power_mode < POWER_MODE_NORMAL) + if(ril_state.power_mode < POWER_MODE_NORMAL) return; memset(&ss, 0, sizeof(ss)); @@ -40,14 +57,14 @@ void respondIconSignalStrength(RIL_Token t, void *data, int length) RIL_onUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, &ss, sizeof(ss)); } -void respondSignalStrength(RIL_Token t, void *data, int length) +void ipc_disp_rssi_info(struct ipc_message_info *info) { - struct ipc_disp_rssi_info *rssi_info = (struct ipc_disp_rssi_info*)data; + struct ipc_disp_rssi_info *rssi_info = (struct ipc_disp_rssi_info *) info->data; RIL_SignalStrength ss; int rssi; /* Don't consider this if modem isn't in normal power mode. */ - if(radio.power_mode < POWER_MODE_NORMAL) + if(ril_state.power_mode < POWER_MODE_NORMAL) return; memset(&ss, 0, sizeof(ss)); diff --git a/include/samsung-ril-socket.h b/include/samsung-ril-socket.h index 6686932..4c3fc1b 100644 --- a/include/samsung-ril-socket.h +++ b/include/samsung-ril-socket.h @@ -1,37 +1,81 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + /* Samsung RIL Socket protocol defines */ +#ifndef _SAMSUNG_RIL_SOCKET_H_ +#define _SAMSUNG_RIL_SOCKET_H_ + #define SRS_COMMAND(f) ((f->group << 8) | f->index) #define SRS_GROUP(m) (m >> 8) #define SRS_INDEX(m) (m & 0xff) +#define SRS_SOCKET_NAME "samsung-ril-socket" +#define SRS_DATA_MAX_SIZE 0x1000 + #define SRS_CONTROL 0x01 -#define SRS_CONTROL_GET_HELO 0x0102 -#define SRS_CONTROL_LINK_CLOSE 0x0103 +#define SRS_CONTROL_PING 0x0101 #define SRS_SND 0x02 #define SRS_SND_SET_CALL_VOLUME 0x0201 #define SRS_SND_SET_CALL_AUDIO_PATH 0x0202 #define SRS_SND_SET_CALL_CLOCK_SYNC 0x0203 -#define SRS_CONTROL_HELO 0xCAFFE +#define SRS_CONTROL_CAFFE 0xCAFFE -#define SRS_CONTROL_LINK_STATUS_OPEN 0x01 -#define SRS_CONTROL_LINK_STATUS_CLOSE 0x02 +enum srs_snd_type { + SRS_SND_TYPE_VOICE, + SRS_SND_TYPE_SPEAKER, + SRS_SND_TYPE_HEADSET, + SRS_SND_TYPE_BTVOICE +}; -#define SRS_SOCKET_NAME "samsung-ril-socket" -#define SRS_DATA_MAX_SIZE 0x1000 +enum srs_snd_path { + SRS_SND_PATH_HANDSET, + SRS_SND_PATH_HEADSET, + SRS_SND_PATH_SPEAKER, + SRS_SND_PATH_BLUETOOTH, + SRS_SND_PATH_BLUETOOTH_NO_NR, + SRS_SND_PATH_HEADPHONE +}; + +enum srs_snd_clock { + SND_CLOCK_STOP, + SND_CLOCK_START +}; + +struct srs_snd_call_volume { + enum srs_snd_type type; + int volume; +} __attribute__((__packed__)); struct srs_header { unsigned int length; unsigned char group; unsigned char index; - unsigned char msg_id; } __attribute__((__packed__)); struct srs_message { unsigned short command; - unsigned char msg_id; int data_len; void *data; } __attribute__((__packed__)); +#endif @@ -0,0 +1,216 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#define LOG_TAG "RIL-IPC" +#include <utils/Log.h> + +#include "samsung-ril.h" +#include <radio.h> + +void ipc_log_handler(const char *message, void *user_data) +{ + LOGD("ipc: %s", message); +} + +void ipc_fmt_send(const unsigned short command, const char type, unsigned char *data, const int length, unsigned char mseq) +{ + struct ipc_client *ipc_client; + + if(ipc_fmt_client == NULL) { + LOGE("ipc_fmt_client is null, aborting!"); + return; + } + + if(ipc_fmt_client->object == NULL) { + LOGE("ipc_fmt_client object is null, aborting!"); + return; + } + + ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client; + + pthread_mutex_lock(&(ipc_fmt_client->mutex)); + ipc_client_send(ipc_client, command, type, data, length, mseq); + pthread_mutex_unlock(&(ipc_fmt_client->mutex)); +} + +int ipc_fmt_read_loop(struct ril_client *client) +{ + struct ipc_message_info info; + struct ipc_client *ipc_client; + int ipc_client_fd; + fd_set fds; + + if(client == NULL) { + LOGE("client is NULL, aborting!"); + return -1; + } + + if(client->object == NULL) { + LOGE("client object is NULL, aborting!"); + return -1; + } + + ipc_client = ((struct ipc_client_object *) client->object)->ipc_client; + ipc_client_fd = ((struct ipc_client_object *) client->object)->ipc_client_fd; + + FD_ZERO(&fds); + FD_SET(ipc_client_fd, &fds); + + while(1) { + if(ipc_client_fd < 0) { + LOGE("IPC FMT client fd is negative, aborting!"); + return -1; + } + + select(FD_SETSIZE, &fds, NULL, NULL, NULL); + + if(FD_ISSET(ipc_client_fd, &fds)) { + if(ipc_client_recv(ipc_client, &info)) { + LOGE("IPC FMT recv failed, aborting!"); + return -1; + } + LOGD("IPC FMT recv: aseq=0x%x mseq=0x%x data_length=%d\n", info.aseq, info.mseq, info.length); + + ipc_fmt_dispatch(&info); + + if(info.data != NULL) + free(info.data); + } + } + + return 0; +} + +int ipc_fmt_create(struct ril_client *client) +{ + struct ipc_client_object *client_object; + struct ipc_client *ipc_client; + int ipc_client_fd; + int rc; + + client_object = malloc(sizeof(struct ipc_client_object)); + memset(client_object, 0, sizeof(struct ipc_client_object)); + client_object->ipc_client_fd = -1; + + client->object = client_object; + + ipc_client = (struct ipc_client *) client_object->ipc_client; + + LOGD("Creating new FMT client"); + ipc_client = ipc_client_new(IPC_CLIENT_TYPE_FMT); + + if(ipc_client == NULL) { + LOGE("FMT client creation failed!"); + return -1; + } + + client_object->ipc_client = ipc_client; + + LOGD("Setting log handler"); + rc = ipc_client_set_log_handler(ipc_client, ipc_log_handler, NULL); + + if(rc < 0) { + LOGE("Setting log handler failed!"); + return -1; + } + + //FIXME: ipc_client_set_handler + + LOGD("Passing client->object->ipc_client fd as handlers data"); + rc = ipc_client_set_all_handlers_data(ipc_client, &((struct ipc_client_object *) client->object)->ipc_client_fd); + + if(rc < 0) { + LOGE("ipc_client_fd as handlers data failed!"); + return -1; + } + + + LOGD("Starting modem bootstrap"); + rc = ipc_client_bootstrap_modem(ipc_client); + + if(rc < 0) { + LOGE("Modem bootstrap failed!"); + return -1; + } + + LOGD("Client open..."); + if(ipc_client_open(ipc_client)) { + LOGE("%s: failed to open ipc client", __FUNCTION__); + return -1; + } + + ipc_client_fd = ((struct ipc_client_object *) client->object)->ipc_client_fd; + + if(ipc_client_fd < 0) { + LOGE("%s: client_fmt_fd is negative, aborting", __FUNCTION__); + return -1; + } + + LOGD("Client power on..."); + if(ipc_client_power_on(ipc_client)) { + LOGE("%s: failed to power on ipc client", __FUNCTION__); + return -1; + } + + return 0; +} + +int ipc_fmt_destroy(struct ril_client *client) +{ + struct ipc_client *ipc_client; + int ipc_client_fd; + int rc; + + LOGD("Destrying ipc fmt client"); + + if(client == NULL) { + LOGE("client was already destroyed"); + return 0; + } + + if(client->object == NULL) { + LOGE("client object was already destroyed"); + return 0; + } + + ipc_client_fd = ((struct ipc_client_object *) client->object)->ipc_client_fd; + + if(ipc_client_fd) + close(ipc_client_fd); + + ipc_client = ((struct ipc_client_object *) client->object)->ipc_client; + + if(ipc_client != NULL) { + ipc_client_power_off(ipc_client); + ipc_client_close(ipc_client); + ipc_client_free(ipc_client); + } + + free(client->object); + + return 0; +} + +struct ril_client_funcs ipc_fmt_client_funcs = { + .create = ipc_fmt_create, + .destroy = ipc_fmt_destroy, + .read_loop = ipc_fmt_read_loop, +}; @@ -0,0 +1,45 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef _SAMSUNG_RIL_IPC_H_ +#define _SAMSUNG_RIL_IPC_H_ + +#include "samsung-ril.h" + +#define ipc_fmt_send_get(command, mseq) \ + ipc_fmt_send(command, IPC_TYPE_GET, NULL, 0, mseq) + +#define ipc_fmt_send_set(command, mseq, data, length) \ + ipc_fmt_send(command, IPC_TYPE_SET, data, length, mseq) + +#define ipc_fmt_send_exec(command, mseq) \ + ipc_fmt_send(command, IPC_TYPE_EXEC, NULL, 0, mseq) + +struct ipc_client_object { + struct ipc_client *ipc_client; + int ipc_client_fd; +}; + +extern struct ril_client_funcs ipc_fmt_client_funcs; + +void ipc_fmt_send(const unsigned short command, const char type, unsigned char *data, const int length, unsigned char mseq); + +#endif @@ -1,26 +1,51 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-MISC" #include <utils/Log.h> #include "samsung-ril.h" +#include "util.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; +// FIXME: there was a problem with IMEI handling *think hard* -void respondNitz(void *data, int length) +void ril_request_get_imei(RIL_Token t) { - struct ipc_misc_time_info *nitz = (struct ipc_misc_time_info*)data; - char str[128]; + char data; - sprintf(str, "%02u/%02u/%02u,%02u:%02u:%02u+%02d,%02d", - nitz->year, nitz->mon, nitz->day, nitz->hour, nitz->min, nitz->sec, nitz->tz, 0); + if(ril_state.radio_state != RADIO_STATE_OFF) { + data = IPC_MISC_ME_SN_SERIAL_NUM; - RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED, str, strlen(str) + 1); + ipc_fmt_send(IPC_MISC_ME_SN, IPC_TYPE_GET, (unsigned char *) &data, sizeof(data), reqGetId(t)); + } else { + ril_state.tokens.get_imei = t; + } } -// TODO: implement RIL_REQUEST_DEVICE_IDENTITY also +void ril_request_get_imeisv(RIL_Token t) +{ + ril_state.tokens.get_imeisv = t; +} -void respondIMEI(RIL_Token t, void *data, int length) +void ipc_misc_me_sn_imei(RIL_Token t, void *data, int length) { struct ipc_misc_me_sn *imei_info; char imei[33]; @@ -28,7 +53,7 @@ void respondIMEI(RIL_Token t, void *data, int length) imei_info = (struct ipc_misc_me_sn *) data; - if(radio.tokens.get_imei != 0 && radio.tokens.get_imei != t) + if(ril_state.tokens.get_imei != 0 && ril_state.tokens.get_imei != t) LOGE("IMEI tokens mismatch"); if(imei_info->length > 32) @@ -44,24 +69,22 @@ void respondIMEI(RIL_Token t, void *data, int length) /* IMEI */ RIL_onRequestComplete(t, RIL_E_SUCCESS, imei, sizeof(char *)); - radio.tokens.get_imei = 0; + ril_state.tokens.get_imei = 0; /* IMEI SV */ - if(radio.tokens.get_imeisv != 0) { - RIL_onRequestComplete(radio.tokens.get_imeisv, RIL_E_SUCCESS, imeisv, sizeof(char *)); - radio.tokens.get_imeisv = 0; + if(ril_state.tokens.get_imeisv != 0) { + RIL_onRequestComplete(ril_state.tokens.get_imeisv, RIL_E_SUCCESS, imeisv, sizeof(char *)); + ril_state.tokens.get_imeisv = 0; } } -void respondMeSn(RIL_Token t, void *data, int length) +void ipc_misc_me_sn(struct ipc_message_info *info) { - struct ipc_misc_me_sn *me_sn_info; - - me_sn_info = (struct ipc_misc_me_sn *) data; + struct ipc_misc_me_sn *me_sn_info = (struct ipc_misc_me_sn *) info->data; switch(me_sn_info->type) { case IPC_MISC_ME_SN_SERIAL_NUM: - respondIMEI(t, data, length); + ipc_misc_me_sn_imei(reqGetToken(info->aseq), info->data, info->length); break; case IPC_MISC_ME_SN_SERIAL_NUM_SERIAL: LOGD("Got IPC_MISC_ME_SN_SERIAL_NUM_SERIAL: %s\n", me_sn_info->data); @@ -69,41 +92,81 @@ void respondMeSn(RIL_Token t, void *data, int length) } } -void requestIMEI(RIL_Token t) +void ril_request_baseband_version(RIL_Token t) { - char data; - - if(radio.radio_state != RADIO_STATE_OFF) { - data = IPC_MISC_ME_SN_SERIAL_NUM; - - ipc_client_send(ipc_client, IPC_MISC_ME_SN, IPC_TYPE_GET, (unsigned char *) &data, sizeof(data), getRequestId(t)); + if(ril_state.radio_state != RADIO_STATE_OFF) { + ipc_fmt_send_get(IPC_MISC_ME_VERSION, reqGetId(t)); } else { - radio.tokens.get_imei = t; + ril_state.tokens.baseband_version = t; } } -void requestIMEISV(RIL_Token t) +void ipc_misc_me_version(struct ipc_message_info *info) { - radio.tokens.get_imeisv = t; + char sw_version[33]; + struct ipc_misc_me_version *version = (struct ipc_misc_me_version *) info->data; + + memcpy(sw_version, version->sw_version, 32); + sw_version[32] = '\0'; + + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, sw_version, sizeof(sw_version)); } -void requestBasebandVersion(RIL_Token t) +/** + * In: RIL_REQUEST_GET_IMSI + * Get the SIM IMSI + * Only valid when radio state is "RADIO_STATE_SIM_READY" + * + * Out: IPC_MISC_ME_IMSI + * Requests ME's IMSI + */ +void ril_request_get_imsi(RIL_Token t) { - if(radio.radio_state != RADIO_STATE_OFF) { - ipc_client_send_get(IPC_MISC_ME_VERSION, getRequestId(t)); - } else { - radio.tokens.baseband_version = t; - } + ipc_fmt_send_get(IPC_MISC_ME_IMSI, reqGetId(t)); } -void respondBasebandVersion(struct ipc_message_info *request) +/** + * In: IPC_MISC_ME_IMSI + * Provides ME's IMSI + * + * Out: RIL_REQUEST_GET_IMSI + * Get the SIM IMSI + * Only valid when radio state is "RADIO_STATE_SIM_READY" + */ +void ipc_misc_me_imsi(struct ipc_message_info *info) { - char sw_version[33]; - struct ipc_misc_me_version *version = (struct ipc_misc_me_version*)request->data; + unsigned char *imsi_length; + char *imsi; - memcpy(sw_version, version->sw_version, 32); - sw_version[32] = '\0'; + if(info->length < 1) { + LOGE("%s: zero data length", __FUNCTION__); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); + return; + } + + imsi_length = (unsigned char*) info->data; + + if(((int) info->length) < *imsi_length + 1) { + LOGE("%s: missing IMSI data", __FUNCTION__); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); + return; + } + + /* Copy IMSI */ + imsi = (char*) malloc(*imsi_length+1); + memcpy(imsi, ((unsigned char*) info->data) + 1, *imsi_length); + imsi[*imsi_length] = '\0'; - RIL_onRequestComplete(getToken(request->aseq), RIL_E_SUCCESS, sw_version, sizeof(sw_version)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, imsi, *imsi_length+1); } +void ipc_misc_time_info(struct ipc_message_info *info) +{ + struct ipc_misc_time_info *nitz = (struct ipc_misc_time_info*) info->data; + char str[128]; + + sprintf(str, "%02u/%02u/%02u,%02u:%02u:%02u+%02d,%02d", + nitz->year, nitz->mon, nitz->day, nitz->hour, nitz->min, nitz->sec, nitz->tz, 0); + + RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED, str, strlen(str) + 1); +} @@ -1,3 +1,24 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-NET" #include <utils/Log.h> @@ -6,10 +27,6 @@ #define RIL_TOKEN_NET_DATA_WAITING (RIL_Token) 0xff -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; - /** * NET Utility functions */ @@ -164,9 +181,9 @@ void gprs_reg_state_resp_ipc2ril(struct ipc_net_regist *netinfo, char *response[ */ void net_set_tokens_data_waiting(void) { - radio.tokens.registration_state = RIL_TOKEN_NET_DATA_WAITING; - radio.tokens.gprs_registration_state = RIL_TOKEN_NET_DATA_WAITING; - radio.tokens.operator = RIL_TOKEN_NET_DATA_WAITING; + ril_state.tokens.registration_state = RIL_TOKEN_NET_DATA_WAITING; + ril_state.tokens.gprs_registration_state = RIL_TOKEN_NET_DATA_WAITING; + ril_state.tokens.operator = RIL_TOKEN_NET_DATA_WAITING; } /** @@ -174,7 +191,7 @@ void net_set_tokens_data_waiting(void) */ int net_get_tokens_data_waiting(void) { - return radio.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING || radio.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING || radio.tokens.operator == RIL_TOKEN_NET_DATA_WAITING; + return ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING || ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING || ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING; } /** @@ -182,7 +199,7 @@ int net_get_tokens_data_waiting(void) */ void net_tokens_state_dump(void) { - LOGD("NET_TOKENS_STATE_DUMP:\n\tradio.tokens.registration_state = 0x%x\n\tradio.tokens.gprs_registration_state = 0x%x\n\tradio.tokens.operator = 0x%x\n", radio.tokens.registration_state, radio.tokens.gprs_registration_state, radio.tokens.operator); + LOGD("NET_TOKENS_STATE_DUMP:\n\tril_state.tokens.registration_state = 0x%x\n\tril_state.tokens.gprs_registration_state = 0x%x\n\tril_state.tokens.operator = 0x%x\n", ril_state.tokens.registration_state, ril_state.tokens.gprs_registration_state, ril_state.tokens.operator); } /** @@ -232,26 +249,27 @@ void net_tokens_state_dump(void) * request IPC_NET_CURRENT_PLMN if no data is there * return RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW if not registered */ -void requestOperator(RIL_Token t) +void ril_request_operator(RIL_Token t) { char *response[3]; int i; - if(radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_EMERGENCY || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN) { + // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value + if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || + ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || + ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN || + ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) { RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0); - radio.tokens.operator = (RIL_Token) 0x00; + ril_state.tokens.operator = (RIL_Token) 0x00; return; } - if(radio.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) { + if(ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Got RILJ request for UNSOL data"); /* Send back the data we got UNSOL */ - plmn_ipc2ril(&(radio.plmndata), response); + plmn_ipc2ril(&(ril_state.plmndata), response); RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); @@ -260,13 +278,13 @@ void requestOperator(RIL_Token t) free(response[i]); } - radio.tokens.operator = (RIL_Token) 0x00; - } else if(radio.tokens.operator == (RIL_Token) 0x00) { + ril_state.tokens.operator = (RIL_Token) 0x00; + } else if(ril_state.tokens.operator == (RIL_Token) 0x00) { LOGD("Got RILJ request for SOL data"); /* Request data to the modem */ - radio.tokens.operator = t; + ril_state.tokens.operator = t; - ipc_client_send_get(IPC_NET_CURRENT_PLMN, getRequestId(t)); + ipc_fmt_send_get(IPC_NET_CURRENT_PLMN, reqGetId(t)); } else { LOGE("Another request is going on, reporting failure"); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, response, sizeof(response)); @@ -284,9 +302,9 @@ void requestOperator(RIL_Token t) * RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED * if SOL message, send back data to RILJ */ -void respondOperator(struct ipc_message_info *message) +void ipc_net_current_plmn(struct ipc_message_info *message) { - RIL_Token t = getToken(message->aseq); + RIL_Token t = reqGetToken(message->aseq); struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn *) message->data; char *response[3]; @@ -296,24 +314,25 @@ void respondOperator(struct ipc_message_info *message) case IPC_TYPE_NOTI: LOGD("Got UNSOL Operator message"); - if(radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_EMERGENCY || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN) { + // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value + if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || + ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || + ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN || + ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) { /* Better keeping it up to date */ - memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); + memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); return; } else { - if(radio.tokens.operator != (RIL_Token) 0x00 && radio.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) { + if(ril_state.tokens.operator != (RIL_Token) 0x00 && ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) { LOGE("Another Operator Req is in progress, skipping"); return; } - memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); + memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); /* we already told RILJ to get the new data but it wasn't done yet */ - if(net_get_tokens_data_waiting() && radio.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) { + if(net_get_tokens_data_waiting() && ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Updating Operator data in background"); } else { net_set_tokens_data_waiting(); @@ -322,24 +341,25 @@ void respondOperator(struct ipc_message_info *message) } break; case IPC_TYPE_RESP: - if(radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_EMERGENCY || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || - radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN) { + // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value + if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || + ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || + ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN || + ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) { /* Better keeping it up to date */ - memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); + memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0); - if(radio.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) - radio.tokens.operator = (RIL_Token) 0x00; + if(ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) + ril_state.tokens.operator = (RIL_Token) 0x00; return; } else { - if(radio.tokens.operator != t) + if(ril_state.tokens.operator != t) LOGE("Operator tokens mismatch"); /* Better keeping it up to date */ - memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); + memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); plmn_ipc2ril(plmndata, response); @@ -350,8 +370,8 @@ void respondOperator(struct ipc_message_info *message) free(response[i]); } - if(radio.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) - radio.tokens.operator = (RIL_Token) 0x00; + if(ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) + ril_state.tokens.operator = (RIL_Token) 0x00; } break; default: @@ -370,17 +390,17 @@ void respondOperator(struct ipc_message_info *message) * return modem UNSOL data if available * request IPC_NET_REGIST if no data is there */ -void requestRegistrationState(RIL_Token t) +void ril_request_registration_state(RIL_Token t) { struct ipc_net_regist_get regist_req; char *response[4]; int i; - if(radio.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) { + if(ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Got RILJ request for UNSOL data"); /* Send back the data we got UNSOL */ - reg_state_resp_ipc2ril(&(radio.netinfo), response); + reg_state_resp_ipc2ril(&(ril_state.netinfo), response); RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); @@ -389,14 +409,14 @@ void requestRegistrationState(RIL_Token t) free(response[i]); } - radio.tokens.registration_state = (RIL_Token) 0x00; - } else if(radio.tokens.registration_state == (RIL_Token) 0x00) { + ril_state.tokens.registration_state = (RIL_Token) 0x00; + } else if(ril_state.tokens.registration_state == (RIL_Token) 0x00) { LOGD("Got RILJ request for SOL data"); /* Request data to the modem */ - radio.tokens.registration_state = t; + ril_state.tokens.registration_state = t; ipc_net_regist_get(®ist_req, IPC_NET_SERVICE_DOMAIN_GSM); - ipc_client_send(ipc_client, IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), getRequestId(t)); + ipc_fmt_send(IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), reqGetId(t)); } else { LOGE("Another request is going on, reporting failure"); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); @@ -413,17 +433,17 @@ void requestRegistrationState(RIL_Token t) * return modem UNSOL data if available * request IPC_NET_REGIST if no data is there */ -void requestGPRSRegistrationState(RIL_Token t) +void ril_request_gprs_registration_state(RIL_Token t) { struct ipc_net_regist_get regist_req; char *response[4]; int i; - if(radio.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) { + if(ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Got RILJ request for UNSOL data"); /* Send back the data we got UNSOL */ - gprs_reg_state_resp_ipc2ril(&(radio.gprs_netinfo), response); + gprs_reg_state_resp_ipc2ril(&(ril_state.gprs_netinfo), response); RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); @@ -432,15 +452,15 @@ void requestGPRSRegistrationState(RIL_Token t) free(response[i]); } - radio.tokens.gprs_registration_state = (RIL_Token) 0x00; - } else if(radio.tokens.gprs_registration_state == (RIL_Token) 0x00) { + ril_state.tokens.gprs_registration_state = (RIL_Token) 0x00; + } else if(ril_state.tokens.gprs_registration_state == (RIL_Token) 0x00) { LOGD("Got RILJ request for SOL data"); /* Request data to the modem */ - radio.tokens.gprs_registration_state = t; + ril_state.tokens.gprs_registration_state = t; ipc_net_regist_get(®ist_req, IPC_NET_SERVICE_DOMAIN_GPRS); - ipc_client_send(ipc_client, IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), getRequestId(t)); + ipc_fmt_send(IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), reqGetId(t)); } else { LOGE("Another request is going on, reporting failure"); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); @@ -449,7 +469,7 @@ void requestGPRSRegistrationState(RIL_Token t) net_tokens_state_dump(); } -void respondNetRegistUnsol(struct ipc_message_info *message) +void ipc_net_regist_unsol(struct ipc_message_info *message) { struct ipc_net_regist *netinfo; netinfo = (struct ipc_net_regist *) message->data; @@ -458,15 +478,15 @@ void respondNetRegistUnsol(struct ipc_message_info *message) switch(netinfo->domain) { case IPC_NET_SERVICE_DOMAIN_GSM: - if(radio.tokens.registration_state != (RIL_Token) 0 && radio.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) { + if(ril_state.tokens.registration_state != (RIL_Token) 0 && ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) { LOGE("Another NetRegist Req is in progress, skipping"); return; } - memcpy(&(radio.netinfo), netinfo, sizeof(struct ipc_net_regist)); + memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist)); /* we already told RILJ to get the new data but it wasn't done yet */ - if(net_get_tokens_data_waiting() && radio.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) { + if(net_get_tokens_data_waiting() && ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Updating NetRegist data in background"); } else { net_set_tokens_data_waiting(); @@ -475,15 +495,15 @@ void respondNetRegistUnsol(struct ipc_message_info *message) break; case IPC_NET_SERVICE_DOMAIN_GPRS: - if(radio.tokens.gprs_registration_state != (RIL_Token) 0 && radio.tokens.gprs_registration_state != RIL_TOKEN_NET_DATA_WAITING) { + if(ril_state.tokens.gprs_registration_state != (RIL_Token) 0 && ril_state.tokens.gprs_registration_state != RIL_TOKEN_NET_DATA_WAITING) { LOGE("Another GPRS NetRegist Req is in progress, skipping"); return; } - memcpy(&(radio.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist)); + memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist)); /* we already told RILJ to get the new data but it wasn't done yet */ - if(net_get_tokens_data_waiting() && radio.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) { + if(net_get_tokens_data_waiting() && ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Updating GPRSNetRegist data in background"); } else { net_set_tokens_data_waiting(); @@ -498,23 +518,23 @@ void respondNetRegistUnsol(struct ipc_message_info *message) net_tokens_state_dump(); } -void respondNetRegistSol(struct ipc_message_info *message) +void ipc_net_regist_sol(struct ipc_message_info *message) { char *response[4]; int i; struct ipc_net_regist *netinfo = (struct ipc_net_regist *) message->data; - RIL_Token t = getToken(message->aseq); + RIL_Token t = reqGetToken(message->aseq); LOGD("Got SOL NetRegist message"); switch(netinfo->domain) { case IPC_NET_SERVICE_DOMAIN_GSM: - if(radio.tokens.registration_state != t) + if(ril_state.tokens.registration_state != t) LOGE("Registration state tokens mismatch"); /* Better keeping it up to date */ - memcpy(&(radio.netinfo), netinfo, sizeof(struct ipc_net_regist)); + memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist)); reg_state_resp_ipc2ril(netinfo, response); @@ -525,15 +545,15 @@ void respondNetRegistSol(struct ipc_message_info *message) free(response[i]); } - if(radio.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) - radio.tokens.registration_state = (RIL_Token) 0x00; + if(ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) + ril_state.tokens.registration_state = (RIL_Token) 0x00; break; case IPC_NET_SERVICE_DOMAIN_GPRS: - if(radio.tokens.gprs_registration_state != t) + if(ril_state.tokens.gprs_registration_state != t) LOGE("GPRS registration state tokens mismatch"); /* Better keeping it up to date */ - memcpy(&(radio.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist)); + memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist)); gprs_reg_state_resp_ipc2ril(netinfo, response); @@ -543,8 +563,8 @@ void respondNetRegistSol(struct ipc_message_info *message) if(response[i] != NULL) free(response[i]); } - if(radio.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) - radio.tokens.gprs_registration_state = (RIL_Token) 0x00; + if(ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) + ril_state.tokens.gprs_registration_state = (RIL_Token) 0x00; break; default: LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain); @@ -558,18 +578,18 @@ void respondNetRegistSol(struct ipc_message_info *message) * In: IPC_NET_REGIST * This can be SOL (RESP) or UNSOL (NOTI) message from modem */ -void respondNetRegist(struct ipc_message_info *message) +void ipc_net_regist(struct ipc_message_info *message) { /* Don't consider this if modem isn't in normal power mode. */ - if(radio.power_mode < POWER_MODE_NORMAL) + if(ril_state.power_mode < POWER_MODE_NORMAL) return; switch(message->type) { case IPC_TYPE_NOTI: - respondNetRegistUnsol(message); + ipc_net_regist_unsol(message); break; case IPC_TYPE_RESP: - respondNetRegistSol(message); + ipc_net_regist_sol(message); break; default: LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type); @@ -578,42 +598,14 @@ void respondNetRegist(struct ipc_message_info *message) } -void requestGetPreferredNetworkType(RIL_Token t) -{ - ipc_client_send_get(IPC_NET_MODE_SEL, getRequestId(t)); -} - -void respondModeSel(struct ipc_message_info *request) -{ - unsigned char ipc_mode = *(unsigned char*)request->data; - int ril_mode = modesel_ipc2ril(ipc_mode); - - RIL_onRequestComplete(getToken(request->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int*)); -} - -void requestSetPreferredNetworkType(RIL_Token t, void *data, size_t datalen) -{ - int ril_mode = *(int*)data; - unsigned char ipc_mode = modesel_ril2ipc(ril_mode); - - ipc_client_send(ipc_client, IPC_NET_MODE_SEL, IPC_TYPE_SET, &ipc_mode, sizeof(ipc_mode), getRequestId(t)); -} - -// FIXME: add corect implementation -void requestNwSelectionMode(RIL_Token t) -{ - unsigned int mode = 0; - RIL_onRequestComplete(t, RIL_E_SUCCESS, &mode, sizeof(mode)); -} - /** * In: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS * * Out: IPC_NET_PLMN_LIST */ -void requestAvailNetworks(RIL_Token t) +void ril_request_query_available_networks(RIL_Token t) { - ipc_client_send_get(IPC_NET_PLMN_LIST, getRequestId(t)); + ipc_fmt_send_get(IPC_NET_PLMN_LIST, reqGetId(t)); } /* FIXME: cleanup struct names & resp[] addressing */ @@ -622,11 +614,11 @@ void requestAvailNetworks(RIL_Token t) * Send back available PLMN list * */ -void respondAvailNetworks(RIL_Token t, void *data, int length) +void ipc_net_plmn_list(struct ipc_message_info *info) { - struct ipc_net_plmn_entries *entries_info = (struct ipc_net_plmn_entries*)data; + struct ipc_net_plmn_entries *entries_info = (struct ipc_net_plmn_entries *) info->data; struct ipc_net_plmn_entry *entries = (struct ipc_net_plmn_entry *) - (data + sizeof(struct ipc_net_plmn_entries)); + (info->data + sizeof(struct ipc_net_plmn_entries)); int i; int size = (4 * entries_info->num * sizeof(char*)); @@ -634,7 +626,9 @@ void respondAvailNetworks(RIL_Token t, void *data, int length) char **resp = malloc(size); char **resp_ptr = resp; -LOGE("Listed %d PLMNs\n", entries_info->num); + + LOGD("Listed %d PLMNs\n", entries_info->num); + for(i = 0; i < entries_info->num; i++) { /* Assumed type for 'emergency only' PLMNs */ if(entries[i].type == 0x01) @@ -675,8 +669,36 @@ LOGE("Listed %d PLMNs\n", entries_info->num); resp_ptr += 4; } - RIL_onRequestComplete(t, RIL_E_SUCCESS, resp, (4 * sizeof(char*) * actual_size)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, resp, (4 * sizeof(char*) * actual_size)); /* FIXME: free individual strings */ free(resp); } + +// FIXME: add corect implementation +void ril_request_query_network_selection_mode(RIL_Token t) +{ + unsigned int mode = 0; + RIL_onRequestComplete(t, RIL_E_SUCCESS, &mode, sizeof(mode)); +} + +void ril_request_get_preferred_network_type(RIL_Token t) +{ + ipc_fmt_send_get(IPC_NET_MODE_SEL, reqGetId(t)); +} + +void ril_request_set_preffered_network_type(RIL_Token t, void *data, size_t datalen) +{ + int ril_mode = *(int*)data; + unsigned char ipc_mode = modesel_ril2ipc(ril_mode); + + ipc_fmt_send(IPC_NET_MODE_SEL, IPC_TYPE_SET, &ipc_mode, sizeof(ipc_mode), reqGetId(t)); +} + +void ipc_net_mode_sel(struct ipc_message_info *info) +{ + unsigned char ipc_mode = *(unsigned char *) info->data; + int ril_mode = modesel_ipc2ril(ipc_mode); + + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int*)); +} @@ -1,25 +1,42 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-PWR" #include <utils/Log.h> #include "samsung-ril.h" #include "util.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; - /** * Out: RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED * Modem lets us know it's powered on. Though, it's still in LPM and should * be considered as OFF. Send this to update RILJ radio state (OFF) */ -void respondPowerUp(void) +void ipc_pwr_phone_pwr_up(void) { /* H1 baseband firmware bug workaround: sleep for 25ms to allow for nvram to initialize */ usleep(25000); - radio.radio_state = RADIO_STATE_OFF; - radio.power_mode = POWER_MODE_LPM; + ril_state.radio_state = RADIO_STATE_OFF; + ril_state.power_mode = POWER_MODE_LPM; RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0); } @@ -31,24 +48,24 @@ void respondPowerUp(void) * Out: RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED * Update radio state according to modem power state */ -void respondPowerPhoneState(struct ipc_message_info *info) +void ipc_pwr_phone_state(struct ipc_message_info *info) { - uint8_t state = *((uint8_t *)info->data); + uint8_t state = *((uint8_t *) info->data); switch(state) { /* This shouldn't append for LPM (no respond message) */ case IPC_PWR_R(IPC_PWR_PHONE_STATE_LPM): - radio.power_mode = POWER_MODE_LPM; - radio.radio_state = RADIO_STATE_OFF; + ril_state.power_mode = POWER_MODE_LPM; + ril_state.radio_state = RADIO_STATE_OFF; LOGD("Got power to LPM"); RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0); break; case IPC_PWR_R(IPC_PWR_PHONE_STATE_NORMAL): usleep(3000); - radio.power_mode = POWER_MODE_NORMAL; - radio.radio_state = RADIO_STATE_SIM_NOT_READY; + ril_state.power_mode = POWER_MODE_NORMAL; + ril_state.radio_state = RADIO_STATE_SIM_NOT_READY; LOGD("Got power to NORMAL"); /* @@ -59,7 +76,7 @@ void respondPowerPhoneState(struct ipc_message_info *info) break; } - RadioTokensCheck(); + ril_tokens_check(); } /** @@ -69,7 +86,7 @@ void respondPowerPhoneState(struct ipc_message_info *info) * Out: IPC_PWR_PHONE_STATE * Order the modem to get in required power mode */ -void requestPower(RIL_Token t, void *data, size_t datalen) +void ril_request_radio_power(RIL_Token t, void *data, size_t datalen) { int power_state = *((int *)data); unsigned short power_data; @@ -79,20 +96,20 @@ void requestPower(RIL_Token t, void *data, size_t datalen) if(power_state > 0) { LOGD("Request power to NORMAL"); power_data = IPC_PWR_PHONE_STATE_NORMAL; - ipc_client_send(ipc_client, IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), getRequestId(t)); + ipc_fmt_send(IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), reqGetId(t)); - radio.tokens.radio_power = t; + ril_state.tokens.radio_power = t; /* Don't tell the RIL we're not off anymore: wait for the message */ } else { LOGD("Request power to LPM"); power_data = IPC_PWR_PHONE_STATE_LPM; - ipc_client_send(ipc_client, IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), getRequestId(t)); + ipc_fmt_send(IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), reqGetId(t)); RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); /* We're not going to get any message to make sure we're in LPM so tell RILJ we're off anyway */ - radio_init_lpm(); + ril_state_lpm(); RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0); } } diff --git a/samsung-ril.c b/samsung-ril.c index d2b4df3..a457b45 100644 --- a/samsung-ril.c +++ b/samsung-ril.c @@ -1,486 +1,426 @@ -#include <time.h> - -#include <telephony/ril.h> +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ -#include <samsung-ril-socket.h> -#include <radio.h> -#include <util.h> +#include <time.h> +#include <pthread.h> #define LOG_TAG "RIL" #include <utils/Log.h> +#include <telephony/ril.h> -#include "socket.h" #include "samsung-ril.h" #include "util.h" #define RIL_VERSION_STRING "Samsung RIL" -const struct RIL_Env *rilenv; -struct radio_state radio; +/** + * Samsung-RIL TODO: + * - add IPC_NET_SERVING_NETWORK + * - client prefix first: ipc2ril_reg_state + * - all these functions on the top + * - use checked function before returning a token to RILJ + */ -struct ipc_client *ipc_client; -struct srs_server *srs_server; -int client_fmt_fd = -1; +/** + * RIL global vars + */ -/* - * Token-related function +struct ril_client *ipc_fmt_client; +struct ril_client *ipc_rfs_client; +struct ril_client *srs_client; + +const struct RIL_Env *ril_env; +struct ril_state ril_state; + +/** + * RIL request token */ -/* Tokens associated with requests */ -RIL_Token request_ids[256]; -int rid = 0; +struct ril_request_token ril_requests_tokens[0x100]; +int ril_request_id = 0; -void read_loop_thread(); +int ril_request_id_new(void) +{ + ril_request_id++; + ril_request_id %= 0x100; + return ril_request_id; +} -int getRequestId(RIL_Token token) +int ril_request_reg_id(RIL_Token token) { - int id = (rid++ % 0x7E); //fixme - request_ids[id] = token; + int id = ril_request_id_new(); - //LOGD("Assigned request id token=%08X id=%02X\n", token, id); + ril_requests_tokens[id].token = token; + ril_requests_tokens[id].canceled = 0; return id; } -void setToken(int id, RIL_Token token) +int ril_request_get_id(RIL_Token token) +{ + int i; + + for(i=0 ; i < 0x100 ; i++) + if(ril_requests_tokens[i].token == token) + return i; + + // If the token isn't registered yet, register it + return ril_request_reg_id(token); +} + +RIL_Token ril_request_get_token(int id) { - request_ids[id] = token; + return ril_requests_tokens[id].token; } -RIL_Token getToken(int id) +int ril_request_is_valid(RIL_Token token) { - //LOGD("Got token=%08X id=%02X\n", request_ids[id], id); - return request_ids[id]; + int id; + + id = ril_request_get_id(token); + + if(ril_requests_tokens[id].canceled > 0) + return 1; + else + return 0; } -void RadioTokensCheck(void) +/** + * RIL tokens + */ + +void ril_tokens_check(void) { - if(radio.tokens.baseband_version != 0) { - if(radio.radio_state != RADIO_STATE_OFF) { - requestBasebandVersion(radio.tokens.baseband_version); - radio.tokens.baseband_version = 0; + if(ril_state.tokens.baseband_version != 0) { + if(ril_state.radio_state != RADIO_STATE_OFF) { + ril_request_baseband_version(ril_state.tokens.baseband_version); + ril_state.tokens.baseband_version = 0; } } - if(radio.tokens.get_imei != 0) { - if(radio.radio_state != RADIO_STATE_OFF) { - requestIMEI(radio.tokens.get_imei); - radio.tokens.get_imei = 0; + if(ril_state.tokens.get_imei != 0) { + if(ril_state.radio_state != RADIO_STATE_OFF) { + ril_request_get_imei(ril_state.tokens.get_imei); + ril_state.tokens.get_imei = 0; } } } -/* - * RILJ (RIL to modem) related functions +/** + * Clients dispatch functions */ -void onRequest(int request, void *data, size_t datalen, RIL_Token t) +void respondGenPhonRes(struct ipc_message_info *info) { - //LOGD("%s: start %d %08X", __FUNCTION__, request, t); -/* - if(radio.tokens.radio_power != 0) { - RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; + struct ipc_gen_phone_res *gen_res = (struct ipc_gen_phone_res*)info->data; + unsigned short msg_type = ((gen_res->group << 8) | gen_res->type); + + if(msg_type == IPC_SEC_PIN_STATUS) { + ipc_sec_pin_status_res(info); + } else { + LOGD("%s: unhandled generic response for msg %04x", __FUNCTION__, msg_type); } -*/ - switch(request) { - case RIL_REQUEST_RADIO_POWER: - requestPower(t, data, datalen); - break; - case RIL_REQUEST_BASEBAND_VERSION: - requestBasebandVersion(t); - break; - case RIL_REQUEST_GET_IMSI: - requestIMSI(t); +} + +void ipc_fmt_dispatch(struct ipc_message_info *info) +{ + switch(IPC_COMMAND(info)) { + /* PWR */ + case IPC_PWR_PHONE_PWR_UP: + ipc_pwr_phone_pwr_up(); break; - case RIL_REQUEST_GET_IMEI: - requestIMEI(t); + case IPC_PWR_PHONE_STATE: + ipc_pwr_phone_state(info); break; - case RIL_REQUEST_GET_IMEISV: - requestIMEISV(t); + /* DISP */ + case IPC_DISP_ICON_INFO: + ipc_disp_icon_info(info); break; - case RIL_REQUEST_OPERATOR: - requestOperator(t); + case IPC_DISP_RSSI_INFO: + ipc_disp_rssi_info(info); break; - case RIL_REQUEST_REGISTRATION_STATE: - requestRegistrationState(t); + /* MISC */ + case IPC_MISC_ME_SN: + ipc_misc_me_sn(info); break; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: - requestGetPreferredNetworkType(t); + case IPC_MISC_ME_VERSION: + ipc_misc_me_version(info); break; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: - requestSetPreferredNetworkType(t, data, datalen); + case IPC_MISC_ME_IMSI: + ipc_misc_me_imsi(info); break; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: - requestNwSelectionMode(t); + case IPC_MISC_TIME_INFO: + ipc_misc_time_info(info); break; - case RIL_REQUEST_GPRS_REGISTRATION_STATE: - requestGPRSRegistrationState(t); + /* SAT */ + case IPC_SAT_PROACTIVE_CMD: + respondSatProactiveCmd(info); break; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: - requestAvailNetworks(t); + case IPC_SAT_ENVELOPE_CMD: + respondSatEnvelopeCmd(info); break; - case RIL_REQUEST_DIAL: - requestDial(t, data, datalen); + /* SIM */ + case IPC_SEC_PIN_STATUS: + ipc_sec_pin_status(info); break; - case RIL_REQUEST_GET_CURRENT_CALLS: - requestGetCurrentCalls(t); + case IPC_SEC_LOCK_INFO: + ipc_sec_lock_info(info); break; - case RIL_REQUEST_HANGUP: - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: - requestHangup(t); + case IPC_SEC_RSIM_ACCESS: + ipc_sec_rsim_access(info); break; - case RIL_REQUEST_ANSWER: - requestAnswer(t); + case IPC_SEC_PHONE_LOCK: + ipc_sec_phone_lock(info); break; - case RIL_REQUEST_DTMF_START: - requestDtmfStart(t, data, datalen); - break; - case RIL_REQUEST_DTMF_STOP: - requestDtmfStop(t); - break; - case RIL_REQUEST_SEND_SMS: - requestSendSms(t, data, datalen); + /* NET */ + case IPC_NET_CURRENT_PLMN: + ipc_net_current_plmn(info); break; - case RIL_REQUEST_SEND_SMS_EXPECT_MORE: - requestSendSmsExpectMore(t, data, datalen); + case IPC_NET_REGIST: + ipc_net_regist(info); break; - case RIL_REQUEST_SMS_ACKNOWLEDGE: - requestSmsAcknowledge(t, data, datalen); + case IPC_NET_PLMN_LIST: + ipc_net_plmn_list(info); break; - case RIL_REQUEST_GET_SIM_STATUS: - requestSimStatus(t); + case IPC_NET_MODE_SEL: + ipc_net_mode_sel(info); break; - case RIL_REQUEST_SIM_IO: - requestSimIo(t, data, datalen); + /* SMS */ + case IPC_SMS_INCOMING_MSG: + ipc_sms_incoming_msg(info); break; - case RIL_REQUEST_ENTER_SIM_PIN: - requestEnterSimPin(t, data, datalen); + case IPC_SMS_DELIVER_REPORT: + ipc_sms_deliver_report(info); break; - case RIL_REQUEST_QUERY_FACILITY_LOCK: - requestQueryFacilityLock(t, data, datalen); + case IPC_SMS_SVC_CENTER_ADDR: + ipc_sms_svc_center_addr(info); break; - case RIL_REQUEST_SET_FACILITY_LOCK: - requestSetFacilityLock(t, data, datalen); + case IPC_SMS_SEND_MSG: + ipc_sms_send_msg(info); break; - case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: - requestSatSendTerminalResponse(t, data, datalen); + case IPC_SMS_DEVICE_READY: + ipc_sms_device_ready(info); break; - case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: - requestSatSendEnvelopeCommand(t, data, datalen); + /* CALL */ + case IPC_CALL_INCOMING: + ipc_call_incoming(info); break; - case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: - RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); + case IPC_CALL_LIST: + ipc_call_list(info); break; - case RIL_REQUEST_SCREEN_STATE: - /* This doesn't affect anything */ - RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); + case IPC_CALL_STATUS: + ipc_call_status(info); break; + /* OTHER */ + case IPC_GEN_PHONE_RES: +// respondGenPhonRes(info); + break; default: - LOGE("Request not implemented: %d\n", request); - RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); + LOGD("Unknown msgtype: %04x", info->type); break; } } -RIL_RadioState currentState() -{ - return radio.radio_state; -} - -int onSupports(int requestCode) +void srs_dispatch(struct srs_message *message) { - switch(requestCode) { - default: - return 1; + switch(message->command) { + case SRS_CONTROL_PING: + srs_control_ping(message); + break; + case SRS_SND_SET_CALL_CLOCK_SYNC: + srs_snd_set_call_clock_sync(message); + break; } } -void onCancel(RIL_Token t) -{ - /* Todo */ -} +/* + * RIL main dispatch function + */ -const char *getVersion(void) +int ril_modem_check(void) { - return RIL_VERSION_STRING; -} + if(ipc_fmt_client == NULL) + return -1; -void respondGenPhonRes(struct ipc_message_info *info) -{ - struct ipc_gen_phone_res *gen_res = (struct ipc_gen_phone_res*)info->data; - unsigned short msg_type = ((gen_res->group << 8) | gen_res->type); + if(ipc_fmt_client->state != RIL_CLIENT_READY) + return -1; - if(msg_type == IPC_SEC_PIN_STATUS) { - respondSecPinStatus(info); - } else { - LOGD("%s: unhandled generic response for msg %04x", __FUNCTION__, msg_type); - } + return 0; } -/** - * libsamsung-ipc (modem to RIL) related functions - */ - -void onReceive(struct ipc_message_info *info) +void onRequest(int request, void *data, size_t datalen, RIL_Token t) { - /* FIXME: This _needs_ to be moved to each individual function. Unsollicited calls do not have a token! */ - RIL_Token t = getToken(info->aseq); - - // TODO: add IPC_NET_SERVING_NETWORK + if(ril_modem_check() < 0) + RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - switch(IPC_COMMAND(info)) { - case IPC_PWR_PHONE_PWR_UP: - respondPowerUp(); + switch(request) { + /* PWR */ + case RIL_REQUEST_RADIO_POWER: + ril_request_radio_power(t, data, datalen); break; - case IPC_PWR_PHONE_STATE: - respondPowerPhoneState(info); + case RIL_REQUEST_BASEBAND_VERSION: + ril_request_baseband_version(t); break; - case IPC_MISC_ME_VERSION: - respondBasebandVersion(info); + /* MISC */ + case RIL_REQUEST_GET_IMEI: + ril_request_get_imei(t); break; - case IPC_MISC_ME_IMSI: - respondIMSI(info); + case RIL_REQUEST_GET_IMEISV: + ril_request_get_imeisv(t); break; - case IPC_MISC_ME_SN: - respondMeSn(t, info->data, info->length); + case RIL_REQUEST_GET_IMSI: + ril_request_get_imsi(t); break; - case IPC_MISC_TIME_INFO: - respondNitz(info->data, info->length); + /* SAT */ + case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: + requestSatSendTerminalResponse(t, data, datalen); break; - case IPC_NET_CURRENT_PLMN: - respondOperator(info); + case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: + requestSatSendEnvelopeCommand(t, data, datalen); break; - case IPC_NET_PLMN_LIST: - respondAvailNetworks(t, info->data, info->length); + case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: + RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); break; - case IPC_NET_REGIST: - respondNetRegist(info); + /* SIM */ + case RIL_REQUEST_GET_SIM_STATUS: + ril_request_sim_status(t); break; - case IPC_NET_MODE_SEL: - respondModeSel(info); + case RIL_REQUEST_SIM_IO: + ril_request_sim_io(t, data, datalen); break; - case IPC_DISP_ICON_INFO: - respondIconSignalStrength(t, info->data, info->length); + case RIL_REQUEST_ENTER_SIM_PIN: + ril_request_enter_sim_pin(t, data, datalen); break; - case IPC_DISP_RSSI_INFO: - respondSignalStrength(t, info->data, info->length); + case RIL_REQUEST_QUERY_FACILITY_LOCK: + ril_request_query_facility_lock(t, data, datalen); break; - case IPC_CALL_INCOMING: - respondCallIncoming(t, info->data, info->length); + case RIL_REQUEST_SET_FACILITY_LOCK: + ril_request_set_facility_lock(t, data, datalen); break; - case IPC_CALL_LIST: - respondCallList(t, info->data, info->length); + /* NET */ + case RIL_REQUEST_OPERATOR: + ril_request_operator(t); break; - case IPC_CALL_STATUS: - respondCallStatus(t, info->data, info->length); + case RIL_REQUEST_REGISTRATION_STATE: + ril_request_registration_state(t); break; - case IPC_SMS_INCOMING_MSG: - respondSmsIncoming(t, info->data, info->length); + case RIL_REQUEST_GPRS_REGISTRATION_STATE: + ril_request_gprs_registration_state(t); break; - case IPC_SMS_DELIVER_REPORT: - respondSmsDeliverReport(t, info->data, info->length); + case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: + ril_request_query_available_networks(t); break; - case IPC_SMS_SVC_CENTER_ADDR: - respondSmsSvcCenterAddr(t, info->data, info->length); + case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: + ril_request_query_network_selection_mode(t); break; - case IPC_SMS_SEND_MSG: - respondSmsSendMsg(t, info->data, info->length); + case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: + ril_request_get_preferred_network_type(t); break; - case IPC_SEC_PIN_STATUS: - respondSimStatusChanged(t, info->data, info->length); + case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: + ril_request_set_preffered_network_type(t, data, datalen); break; - case IPC_SEC_LOCK_INFO: - respondLockInfo(info); + /* SMS */ + case RIL_REQUEST_SEND_SMS: + ril_request_send_sms(t, data, datalen); break; - case IPC_SEC_RSIM_ACCESS: - respondSecRsimAccess(t, info->data, info->length); + case RIL_REQUEST_SEND_SMS_EXPECT_MORE: + ril_request_send_sms_expect_more(t, data, datalen); break; - case IPC_SEC_PHONE_LOCK: - respondSecPhoneLock(info); + case RIL_REQUEST_SMS_ACKNOWLEDGE: + ril_request_sms_acknowledge(t, data, datalen); break; - case IPC_SAT_PROACTIVE_CMD: - respondSatProactiveCmd(info); + /* CALL */ + case RIL_REQUEST_DIAL: + ril_request_dial(t, data, datalen); break; - case IPC_SAT_ENVELOPE_CMD: - respondSatEnvelopeCmd(info); + case RIL_REQUEST_GET_CURRENT_CALLS: + ril_request_get_current_calls(t); break; - case IPC_GEN_PHONE_RES: - respondGenPhonRes(info); + case RIL_REQUEST_HANGUP: + case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: + case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: + ril_request_hangup(t); break; - case IPC_SMS_DEVICE_READY: - respondSmsDeviceReady(t, info); + case RIL_REQUEST_ANSWER: + ril_request_answer(t); + break; + case RIL_REQUEST_DTMF_START: + ril_request_dtmf_start(t, data, datalen); + break; + case RIL_REQUEST_DTMF_STOP: + ril_request_dtmf_stop(t); + break; + /* OTHER */ + case RIL_REQUEST_SCREEN_STATE: + /* This doesn't affect anything */ + RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); break; default: - //LOGD("Unknown msgtype: %04x", info->type); + LOGE("Request not implemented: %d\n", request); + RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); break; } } -void ipc_log_handler(const char *message, void *user_data) -{ - LOGD("ipc: %s", message); -} - -void socketRespondGetHelo(struct srs_message *message) -{ - int helo = SRS_CONTROL_HELO; - srs_server_send(srs_server, SRS_CONTROL_GET_HELO, &helo, sizeof(helo), message->msg_id); -} +/** + * RILJ related functions + */ -void socketRespondLinkClose(struct srs_message *message) +RIL_RadioState currentState() { - close(srs_server->client_fd); - srs_server->client_fd = -1; + return ril_state.radio_state; } -void socketRespondSetCallClockSync(struct srs_message *message) +int onSupports(int requestCode) { - unsigned char data = *((unsigned char *) message->data); - LOGE("SetCallClockSync data is 0x%x\n", data); - - ipc_client_send(ipc_client, IPC_SND_CLOCK_CTRL, IPC_TYPE_EXEC, &data, sizeof(data), 0xff); + switch(requestCode) { + default: + return 1; + } } -void onSocketReceive(struct srs_message *message) +void onCancel(RIL_Token t) { - switch(message->command) { - case SRS_CONTROL_GET_HELO: - socketRespondGetHelo(message); - break; - case SRS_CONTROL_LINK_CLOSE: - socketRespondLinkClose(message); - break; - case SRS_SND_SET_CALL_CLOCK_SYNC: - socketRespondSetCallClockSync(message); - break; - } + /* Todo */ } -void *socket_loop() +const char *getVersion(void) { - struct srs_message srs_message; - fd_set fds; - int rc; - - while(1) { - rc = srs_server_accept(srs_server); - - LOGE("SRS server accept!"); - - FD_ZERO(&fds); - FD_SET(srs_server->client_fd, &fds); - - while(1) { - usleep(300); - - if(srs_server->client_fd < 0) - break; - - select(FD_SETSIZE, &fds, NULL, NULL, NULL); - - if(FD_ISSET(srs_server->client_fd, &fds)) { - if(srs_server_recv(srs_server, &srs_message) < 0) { - LOGE("SRS server RECV failure!!!"); - break; - } - - LOGE("SRS OBTAINED DATA DUMP == %d == %d ======", srs_message.command, srs_message.data_len); - ipc_hex_dump(ipc_client, srs_message.data, srs_message.data_len); - - onSocketReceive(&srs_message); - - if(srs_message.data != NULL) //check on datalen - free(srs_message.data); - } - } - - if(srs_server->client_fd > 0) { - close(srs_server->client_fd); - srs_server->client_fd = -1; - } - - LOGE("SRS server client ended!"); - } - - return 0; + return RIL_VERSION_STRING; } /** - * read_loop(): - * This function is the main RIL read loop + * RIL init function */ -void *read_loop() -{ - struct ipc_message_info resp; - fd_set fds; - - FD_ZERO(&fds); - FD_SET(client_fmt_fd, &fds); - while(1) { - usleep(300); - - select(FD_SETSIZE, &fds, NULL, NULL, NULL); - - if(FD_ISSET(client_fmt_fd, &fds)) { - if(ipc_client_recv(ipc_client, &resp)) { - LOGE("IPC RECV failure!!!"); - break; - } - LOGD("RECV aseq=0x%x mseq=0x%x data_length=%d\n", resp.aseq, resp.mseq, resp.length); - - onReceive(&resp); - - if(resp.data != NULL) - free(resp.data); - } - } - - ipc_client_power_off(ipc_client); - ipc_client_close(ipc_client); - ipc_client_free(ipc_client); - - return 0; -} - -void radio_init_tokens(void) +void ril_state_lpm(void) { - memset(&(radio.tokens), 0, sizeof(struct ril_tokens)); + memset(&ril_state, 0, sizeof(ril_state)); + ril_state.radio_state = RADIO_STATE_OFF; + ril_state.power_mode = POWER_MODE_LPM; } -void radio_init_lpm(void) -{ - memset(&radio, 0, sizeof(radio)); - radio.radio_state = RADIO_STATE_OFF; - radio.power_mode = POWER_MODE_LPM; -} -void socket_loop_thread() -{ - pthread_t thread; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&thread, &attr, socket_loop, NULL); -} - -void read_loop_thread() -{ - pthread_t thread; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&thread, &attr, read_loop, NULL); -} - -/** - * RIL_Init function - */ - -static const RIL_RadioFunctions radio_ops = { +static const RIL_RadioFunctions ril_ops = { RIL_VERSION, onRequest, currentState, @@ -491,48 +431,54 @@ static const RIL_RadioFunctions radio_ops = { const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv) { - radio_init_lpm(); - radio_init_tokens(); + int rc; - rilenv = env; + ril_env = env; - LOGD("Creating new FMT client"); - ipc_client = ipc_client_new(IPC_CLIENT_TYPE_FMT); + ril_state_lpm(); + memset(&(ril_state.tokens), 0, sizeof(struct ril_tokens)); - ipc_client_set_log_handler(ipc_client, ipc_log_handler, NULL); +ipc_fmt: + ipc_fmt_client = ril_client_new(&ipc_fmt_client_funcs); + rc = ril_client_create(ipc_fmt_client); - ipc_client_bootstrap_modem(ipc_client); + if(rc < 0) { + LOGE("IPC FMT client creation failed."); + goto ipc_rfs; + } - LOGD("All handlers data is %p", &client_fmt_fd); - ipc_client_set_all_handlers_data(ipc_client, &client_fmt_fd); + rc = ril_client_thread_start(ipc_fmt_client); - LOGD("Client open..."); - if(ipc_client_open(ipc_client)) { - LOGE("%s: failed to open ipc client", __FUNCTION__); - return 0; + if(rc < 0) { + LOGE("IPC FMT thread creation failed."); + goto ipc_rfs; } - if(client_fmt_fd < 0) { - LOGE("%s: client_fmt_fd is negative, aborting", __FUNCTION__); - return 0; - } + LOGD("IPC FMT client ready"); - LOGD("Client power on..."); - if(ipc_client_power_on(ipc_client)) { - LOGE("%s: failed to power on ipc client", __FUNCTION__); - return 0; +ipc_rfs: + LOGD("Wait for the rest to be working before doing RFS"); + +srs: + srs_client = ril_client_new(&srs_client_funcs); + rc = ril_client_create(srs_client); + + if(rc < 0) { + LOGE("SRS client creation failed."); + goto end; } - srs_server = srs_server_new(); - if(srs_server_open(srs_server) < 0) { - LOGE("%s: samsung-ril-socket server open failed", __FUNCTION__); - return 0; + rc = ril_client_thread_start(srs_client); + + if(rc < 0) { + LOGE("SRS thread creation failed."); + goto end; } - read_loop_thread(); - socket_loop_thread(); + LOGD("SRS client ready"); - return &radio_ops; +end: + return &ril_ops; } int main(int argc, char *argv[]) diff --git a/samsung-ril.h b/samsung-ril.h index db898e8..b34bc76 100644 --- a/samsung-ril.h +++ b/samsung-ril.h @@ -1,19 +1,148 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef _SAMSUNG_RIL_H_ +#define _SAMSUNG_RIL_H_ + +#include <pthread.h> + #include <telephony/ril.h> #include <radio.h> -#define RIL_onRequestComplete(t, e, response, responselen) rilenv->OnRequestComplete(t,e, response, responselen) -#define RIL_onUnsolicitedResponse(a,b,c) rilenv->OnUnsolicitedResponse(a,b,c) -#define RIL_requestTimedCallback(a,b,c) rilenv->RequestTimedCallback(a,b,c) +#include "ipc.h" +#include "srs.h" + +/** + * Defines + */ + +#define RIL_onRequestComplete(t, e, response, responselen) ril_env->OnRequestComplete(t,e, response, responselen) +#define RIL_onRequestCompleteIfValid(t, e, response, responselen) \ + if((ril_request_is_valid(t)) \ + RIL_onRequestComplete(t, e, response, responselen) +#define RIL_onUnsolicitedResponse(a,b,c) ril_env->OnUnsolicitedResponse(a,b,c) +#define RIL_requestTimedCallback(a,b,c) ril_env->RequestTimedCallback(a,b,c) + +#define reqIdNew() ril_request_id_new() +#define reqGetId(t) ril_request_get_id(t) +#define reqGetToken(i) ril_request_get_token(i) + +/** + * RIL structures + */ + +struct ril_client; +struct ril_token; +struct ril_tokens; +struct ril_state; + +/** + * RIL globals + */ + +extern struct ril_client *ipc_fmt_client; +extern struct ril_client *ipc_rfs_client; +extern struct ril_client *srs_client; + +extern const struct RIL_Env *ril_env; +extern struct ril_state ril_state; + +/** + * RIL client + */ + +typedef int (*ril_client_func)(struct ril_client *client); + +typedef enum { + RIL_CLIENT_NULL = 0, + RIL_CLIENT_CREATED = 1, + RIL_CLIENT_READY = 2, + RIL_CLIENT_DESTROYED = 3, + RIL_CLIENT_ERROR = 4, + +} ril_client_state; + +struct ril_client { + ril_client_func create; + ril_client_func destroy; + ril_client_func read_loop; + + void *object; + + pthread_t thread; + pthread_mutex_t mutex; + + ril_client_state state; +}; + +struct ril_client_funcs { + ril_client_func create; + ril_client_func destroy; + ril_client_func read_loop; +}; + +struct ril_client *ril_client_new(struct ril_client_funcs *client_funcs); +int ril_client_free(struct ril_client *client); +int ril_client_create(struct ril_client *client); +int ril_client_destroy(struct ril_client *client); +int ril_client_thread_start(struct ril_client *client); + +/** + * RIL request token + */ + +struct ril_request_token { + RIL_Token token; + int canceled; +}; + +int ril_request_id_new(void); +int ril_request_get_id(RIL_Token token); +RIL_Token ril_request_get_token(int id); +int ril_request_is_valid(RIL_Token token); + +/** + * RIL tokens + */ + +// FIXME: Move RIL_Token token_ps, token_cs; here +struct ril_tokens { + RIL_Token radio_power; + RIL_Token get_imei; + RIL_Token get_imeisv; + RIL_Token baseband_version; -#define ipc_client_send_get(type, request) \ - ipc_client_send(ipc_client, type, IPC_TYPE_GET, NULL, 0, request) + RIL_Token registration_state; + RIL_Token gprs_registration_state; + RIL_Token operator; -#define ipc_client_send_set(type, request, data, len) \ - ipc_client_send(ipc_client, type, IPC_TYPE_SET, data, len, request) + RIL_Token send_sms; +}; -#define ipc_client_send_exec(type, request) \ - ipc_client_send(ipc_client, type, IPC_TYPE_EXEC, NULL, 0, request) +void ril_tokens_check(void); +/** + * RIL state + */ + typedef enum { SIM_ABSENT = 0, SIM_NOT_READY = 1, @@ -33,22 +162,7 @@ typedef enum { POWER_MODE_SIM_INIT_COMPLETE = 4, } Modem_PowerMode; -// Move RIL_Token token_ps, token_cs; here -struct ril_tokens { - RIL_Token radio_power; - RIL_Token get_imei; - RIL_Token get_imeisv; - RIL_Token baseband_version; - - RIL_Token registration_state; - RIL_Token gprs_registration_state; - RIL_Token operator; - - RIL_Token send_sms; -}; - - -struct radio_state { +struct ril_state { RIL_RadioState radio_state; RIL_CardState card_state; SIM_Status sim_status; @@ -64,46 +178,34 @@ struct radio_state { char *msg_pdu; }; -void RadioTokensCheck(void); -int getRequestId(RIL_Token token); -RIL_Token getToken(int id); +void ril_state_lpm(void); +int ril_modem_check(void); -void radio_init_lpm(void); +/** + * Clients dispatch functions + */ -/* Call */ -void requestCallList(RIL_Token t); -void requestGetCurrentCalls(RIL_Token t); -void requestHangup(RIL_Token t); -void requestAnswer(RIL_Token t); -void requestDial(RIL_Token t, void *data, size_t datalen); -void respondCallIncoming(RIL_Token t, void *data, int length); -void respondCallStatus(RIL_Token t, void *data, int length); -void respondCallList(RIL_Token t, void *data, int length); -void requestDtmfStart(RIL_Token t, void *data, int length); -void requestDtmfStop(RIL_Token t); - -/* Misc */ -void requestBasebandVersion(RIL_Token t); -void respondBasebandVersion(struct ipc_message_info *request); - -/* Net */ -void requestGPRSRegistrationState(RIL_Token t); -void respondNetRegist(struct ipc_message_info *request); -void requestGetPreferredNetworkType(RIL_Token t); -void respondModeSel(struct ipc_message_info *request); -void requestSetPreferredNetworkType(RIL_Token t, void *data, size_t datalen); +void ipc_dispatch(struct ipc_message_info *info); -/* SIM */ -void respondSimStatusChanged(RIL_Token t, void *data, int length); -void requestSimStatus(RIL_Token t); -void requestSimIo(RIL_Token t, void *data, size_t datalen); -void respondSecRsimAccess(RIL_Token t, void *data, int length); -void requestEnterSimPin(RIL_Token t, void *data, size_t datalen); -void respondSecPinStatus(struct ipc_message_info *request); -void respondLockInfo(struct ipc_message_info *request); -void requestQueryFacilityLock(RIL_Token t, void *data, size_t datalen); -void respondSecPhoneLock(struct ipc_message_info *request); -void requestSetFacilityLock(RIL_Token t, void *data, size_t datalen); + +/* PWR */ +void ipc_pwr_phone_pwr_up(void); +void ipc_pwr_phone_state(struct ipc_message_info *info); +void ril_request_radio_power(RIL_Token t, void *data, size_t datalen); + +/* DISP */ +void ipc_disp_icon_info(struct ipc_message_info *info); +void ipc_disp_rssi_info(struct ipc_message_info *info); + +/* MISC */ +void ril_request_get_imei(RIL_Token t); +void ril_request_get_imeisv(RIL_Token t); +void ipc_misc_me_sn(struct ipc_message_info *info); +void ril_request_baseband_version(RIL_Token t); +void ipc_misc_me_version(struct ipc_message_info *info); +void ril_request_get_imsi(RIL_Token t); +void ipc_misc_me_imsi(struct ipc_message_info *info); +void ipc_misc_time_info(struct ipc_message_info *info); /* SAT */ void respondSatProactiveCmd(struct ipc_message_info *request); @@ -111,22 +213,54 @@ void requestSatSendTerminalResponse(RIL_Token t, void *data, size_t datalen); void requestSatSendEnvelopeCommand(RIL_Token t, void *data, size_t datalen); void respondSatEnvelopeCmd(struct ipc_message_info *request); +/* SIM */ +void ipc_sec_pin_status(struct ipc_message_info *info); +void ril_request_sim_status(RIL_Token t); +void ril_request_sim_io(RIL_Token t, void *data, size_t datalen); +void ipc_sec_rsim_access(struct ipc_message_info *info); +void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t datalen); +void ipc_sec_pin_status_res(struct ipc_message_info *info); +void ipc_sec_lock_info(struct ipc_message_info *info); +void ril_request_query_facility_lock(RIL_Token t, void *data, size_t datalen); +void ipc_sec_phone_lock(struct ipc_message_info *info); +void ril_request_set_facility_lock(RIL_Token t, void *data, size_t datalen); + +/* NET */ +void ril_request_operator(RIL_Token t); +void ipc_net_current_plmn(struct ipc_message_info *message); +void ril_request_registration_state(RIL_Token t); +void ril_request_gprs_registration_state(RIL_Token t); +void ipc_net_regist(struct ipc_message_info *message); +void ril_request_query_available_networks(RIL_Token t); +void ipc_net_plmn_list(struct ipc_message_info *info); +void ril_request_query_network_selection_mode(RIL_Token t); +void ril_request_get_preferred_network_type(RIL_Token t); +void ril_request_set_preffered_network_type(RIL_Token t, void *data, size_t datalen); +void ipc_net_mode_sel(struct ipc_message_info *info); + /* SMS */ -void respondSmsIncoming(RIL_Token t, void *data, int length); -void requestSendSmsEx(RIL_Token t, void *data, size_t datalen, unsigned char hint); -void requestSendSms(RIL_Token t, void *data, size_t datalen); -void requestSendSmsExpectMore(RIL_Token t, void *data, size_t datalen); -void requestSmsAcknowledge(RIL_Token t, void *data, size_t datalen); -void respondSmsDeviceReady(RIL_Token t, struct ipc_message_info *info); +void ipc_sms_incoming_msg(struct ipc_message_info *info); +void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t datalen); +void ipc_sms_deliver_report(struct ipc_message_info *info); +void ril_request_send_sms(RIL_Token t, void *data, size_t datalen); +void ril_request_send_sms_expect_more(RIL_Token t, void *data, size_t datalen); +void ipc_sms_svc_center_addr(struct ipc_message_info *info); +void ipc_sms_send_msg(struct ipc_message_info *info); +void ipc_sms_device_ready(struct ipc_message_info *info); -void requestIMSI(RIL_Token t); -void respondIMSI(struct ipc_message_info *request); +/* Call */ +void ipc_call_incoming(struct ipc_message_info *info); +void ipc_call_status(struct ipc_message_info *info); +void ril_request_dial(RIL_Token t, void *data, size_t datalen); +void ril_request_get_current_calls(RIL_Token t); +void ipc_call_list(struct ipc_message_info *info); +void ril_request_hangup(RIL_Token t); +void ril_request_answer(RIL_Token t); +void ril_request_dtmf_start(RIL_Token t, void *data, int length); +void ril_request_dtmf_stop(RIL_Token t); -/* PWR */ -void respondPowerUp(void); -void respondPowerPhoneState(struct ipc_message_info *info); -void requestPower(RIL_Token t, void *data, size_t datalen); +/* SND */ -/* DISP */ -void respondIconSignalStrength(RIL_Token t, void *data, int length); -void respondSignalStrength(RIL_Token t, void *data, int length); +void srs_snd_set_call_clock_sync(struct srs_message *message); + +#endif @@ -1,27 +1,44 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-SAT" #include <utils/Log.h> #include "samsung-ril.h" #include "util.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; - /** * In: IPC_SAT_PROACTIVE_CMD * STK proactive command * * Out: RIL_UNSOL_STK_PROACTIVE_COMMAND */ -void respondSatProactiveCmdIndi(struct ipc_message_info *request) +void respondSatProactiveCmdIndi(struct ipc_message_info *info) { - int data_len = (request->length-2); + int data_len = (info->length-2); char *hexdata; hexdata = (char*)malloc(data_len*2+1); - bin2hex((unsigned char*)request->data+2, data_len, hexdata); + bin2hex((unsigned char*)info->data+2, data_len, hexdata); RIL_onUnsolicitedResponse(RIL_UNSOL_STK_PROACTIVE_COMMAND, hexdata, sizeof(char*)); @@ -34,12 +51,12 @@ void respondSatProactiveCmdIndi(struct ipc_message_info *request) * * Out: RIL_UNSOL_STK_SESSION_END */ -void respondSatProactiveCmdResp(struct ipc_message_info *request) +void respondSatProactiveCmdResp(struct ipc_message_info *info) { unsigned char sw1, sw2; - sw1 = ((unsigned char*)request->data)[0]; - sw2 = ((unsigned char*)request->data)[1]; + sw1 = ((unsigned char*)info->data)[0]; + sw2 = ((unsigned char*)info->data)[1]; if(sw1 == 0x90 && sw2 == 0x00) { RIL_onUnsolicitedResponse(RIL_UNSOL_STK_SESSION_END, NULL, 0); @@ -51,14 +68,14 @@ void respondSatProactiveCmdResp(struct ipc_message_info *request) /** * Proactive command indi/resp helper function */ -void respondSatProactiveCmd(struct ipc_message_info *request) +void respondSatProactiveCmd(struct ipc_message_info *info) { - if(request->type == IPC_TYPE_INDI) { - respondSatProactiveCmdIndi(request); - } else if(request->type == IPC_TYPE_RESP) { - respondSatProactiveCmdResp(request); + if(info->type == IPC_TYPE_INDI) { + respondSatProactiveCmdIndi(info); + } else if(info->type == IPC_TYPE_RESP) { + respondSatProactiveCmdResp(info); } else { - LOGE("%s: unhandled proactive command response type %d", __FUNCTION__, request->type); + LOGE("%s: unhandled proactive command response type %d", __FUNCTION__, info->type); } } @@ -84,7 +101,7 @@ void requestSatSendTerminalResponse(RIL_Token t, void *data, size_t datalen) buf[0] = len; hex2bin(data, strlen(data), &buf[1]); - ipc_client_send(ipc_client, IPC_SAT_PROACTIVE_CMD, IPC_TYPE_GET, buf, sizeof(buf), getRequestId(t)); + ipc_fmt_send(IPC_SAT_PROACTIVE_CMD, IPC_TYPE_GET, buf, sizeof(buf), reqGetId(t)); RIL_onRequestComplete(t, RIL_E_SUCCESS, buf, sizeof(char*)); } @@ -111,7 +128,7 @@ void requestSatSendEnvelopeCommand(RIL_Token t, void *data, size_t datalen) buf[0] = len; hex2bin(data, strlen(data), &buf[1]); - ipc_client_send(ipc_client, IPC_SAT_ENVELOPE_CMD, IPC_TYPE_EXEC, buf, sizeof(buf), getRequestId(t)); + ipc_fmt_send(IPC_SAT_ENVELOPE_CMD, IPC_TYPE_EXEC, buf, sizeof(buf), reqGetId(t)); } /** @@ -121,16 +138,16 @@ void requestSatSendEnvelopeCommand(RIL_Token t, void *data, size_t datalen) * Requests to send a SAT/USAT envelope command to SIM. * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 */ -void respondSatEnvelopeCmd(struct ipc_message_info *request) +void respondSatEnvelopeCmd(struct ipc_message_info *info) { - int data_len = (request->length-2); + int data_len = (info->length-2); char *hexdata; hexdata = (char*)malloc(data_len*2+1); - bin2hex((unsigned char*)request->data+2, data_len, hexdata); + bin2hex((unsigned char*)info->data+2, data_len, hexdata); - RIL_onRequestComplete(getToken(request->aseq), RIL_E_SUCCESS, hexdata, sizeof(char*)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, hexdata, sizeof(char*)); free(hexdata); } @@ -1,13 +1,30 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-SIM" #include <utils/Log.h> #include "samsung-ril.h" #include "util.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; - /** * Update the radio state based on SIM status * @@ -15,18 +32,18 @@ extern struct ipc_client *ipc_client; * Indicate when value of RIL_RadioState has changed * Callee will invoke RIL_RadioStateRequest method on main thread */ -void updateRadioState(SIM_Status status) +void ril_state_update(SIM_Status status) { /* If power mode isn't at least normal, don't update RIL state */ - if(radio.power_mode < POWER_MODE_NORMAL) + if(ril_state.power_mode < POWER_MODE_NORMAL) return; switch(status) { case SIM_READY: - radio.radio_state = RADIO_STATE_SIM_READY; + ril_state.radio_state = RADIO_STATE_SIM_READY; break; case SIM_NOT_READY: - radio.radio_state = RADIO_STATE_SIM_NOT_READY; + ril_state.radio_state = RADIO_STATE_SIM_NOT_READY; break; case SIM_ABSENT: case SIM_PIN: @@ -36,14 +53,14 @@ void updateRadioState(SIM_Status status) case SIM_NETWORK_SUBSET_PERSO: case SIM_CORPORATE_PERSO: case SIM_SERVICE_PROVIDER_PERSO: - radio.radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT; + ril_state.radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT; break; default: - radio.radio_state = RADIO_STATE_SIM_NOT_READY; + ril_state.radio_state = RADIO_STATE_SIM_NOT_READY; break; } - RadioTokensCheck(); + ril_tokens_check(); RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0); } @@ -59,59 +76,59 @@ void updateRadioState(SIM_Status status) * Indicate when value of RIL_RadioState has changed * Callee will invoke RIL_RadioStateRequest method on main thread */ -void respondSimStatusChanged(RIL_Token t, void *data, int length) +void ipc_sec_pin_status(struct ipc_message_info *info) { - struct ipc_sec_pin_status_noti *pin_status = (struct ipc_sec_pin_status_noti*)data; + struct ipc_sec_pin_status_noti *pin_status = (struct ipc_sec_pin_status_noti *) info->data; /* Don't consider this if modem isn't in normal power mode. */ - if(radio.power_mode < POWER_MODE_NORMAL) + if(ril_state.power_mode < POWER_MODE_NORMAL) return; - if(radio.power_mode == POWER_MODE_NORMAL && radio.tokens.radio_power != 0) { - RIL_onRequestComplete(radio.tokens.radio_power, RIL_E_SUCCESS, NULL, 0); - radio.tokens.radio_power = 0; + if(ril_state.power_mode == POWER_MODE_NORMAL && ril_state.tokens.radio_power != 0) { + RIL_onRequestComplete(ril_state.tokens.radio_power, RIL_E_SUCCESS, NULL, 0); + ril_state.tokens.radio_power = 0; } /* Determine SIM status */ switch(pin_status->type) { case IPC_SEC_PIN_SIM_INITIALIZING: - radio.sim_status = SIM_NOT_READY; + ril_state.sim_status = SIM_NOT_READY; break; case IPC_SEC_PIN_SIM_LOCK_SC: switch(pin_status->key) { case IPC_SEC_PIN_SIM_LOCK_SC_PIN1_REQ: - radio.sim_status = SIM_PIN; + ril_state.sim_status = SIM_PIN; break; case IPC_SEC_PIN_SIM_LOCK_SC_PUK_REQ: - radio.sim_status = SIM_PUK; + ril_state.sim_status = SIM_PUK; break; case IPC_SEC_PIN_SIM_LOCK_SC_CARD_BLOCKED: - radio.sim_status = SIM_BLOCKED; + ril_state.sim_status = SIM_BLOCKED; break; default: - radio.sim_status = SIM_ABSENT; + ril_state.sim_status = SIM_ABSENT; LOGE("%s: unknown SC substate %d --> setting SIM_ABSENT", __FUNCTION__, pin_status->key); break; } break; case IPC_SEC_PIN_SIM_LOCK_FD: - radio.sim_status = SIM_ABSENT; + ril_state.sim_status = SIM_ABSENT; LOGE("%s: FD lock present (unhandled state --> setting SIM_ABSENT)", __FUNCTION__); break; case IPC_SEC_PIN_SIM_LOCK_PN: - radio.sim_status = SIM_NETWORK_PERSO; + ril_state.sim_status = SIM_NETWORK_PERSO; break; case IPC_SEC_PIN_SIM_LOCK_PU: - radio.sim_status = SIM_NETWORK_SUBSET_PERSO; + ril_state.sim_status = SIM_NETWORK_SUBSET_PERSO; break; case IPC_SEC_PIN_SIM_LOCK_PP: - radio.sim_status = SIM_SERVICE_PROVIDER_PERSO; + ril_state.sim_status = SIM_SERVICE_PROVIDER_PERSO; break; case IPC_SEC_PIN_SIM_LOCK_PC: - radio.sim_status = SIM_CORPORATE_PERSO; + ril_state.sim_status = SIM_CORPORATE_PERSO; break; case IPC_SEC_PIN_SIM_INIT_COMPLETE: - radio.sim_status = SIM_READY; + ril_state.sim_status = SIM_READY; break; case IPC_SEC_PIN_SIM_PB_INIT_COMPLETE: /* Ignore phone book init complete */ @@ -122,12 +139,12 @@ void respondSimStatusChanged(RIL_Token t, void *data, int length) case IPC_SEC_PIN_SIM_CARD_ERROR: default: /* Catchall for locked, card error and unknown states */ - radio.sim_status = SIM_ABSENT; + ril_state.sim_status = SIM_ABSENT; break; } /* Update radio state based on SIM state */ - updateRadioState(radio.sim_status); + ril_state_update(ril_state.sim_status); RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); } @@ -136,7 +153,7 @@ void respondSimStatusChanged(RIL_Token t, void *data, int length) * In: RIL_REQUEST_GET_SIM_STATUS * Requests status of the SIM interface and the SIM card */ -void requestSimStatus(RIL_Token t) +void ril_request_sim_status(RIL_Token t) { static RIL_AppStatus app_status_array[] = { /* SIM_ABSENT = 0 */ @@ -176,7 +193,7 @@ void requestSimStatus(RIL_Token t) RIL_CardStatus card_status; /* Card is assumed to be present if not explicitly absent */ - if(radio.sim_status == SIM_ABSENT) { + if(ril_state.sim_status == SIM_ABSENT) { card_state = RIL_CARDSTATE_ABSENT; } else { card_state = RIL_CARDSTATE_PRESENT; @@ -198,7 +215,7 @@ void requestSimStatus(RIL_Token t) if(card_status.card_state == RIL_CARDSTATE_PRESENT) { card_status.gsm_umts_subscription_app_index = 0; card_status.num_applications = 1; - card_status.applications[0] = app_status_array[radio.sim_status]; + card_status.applications[0] = app_status_array[ril_state.sim_status]; /* FIXME: if USIM, set apptype */ //card_status.applications[0] = RIL_APPTYPE_USIM @@ -217,7 +234,7 @@ void requestSimStatus(RIL_Token t) * Out: IPC_SEC_RSIM_ACCESS * Performs a restricted SIM read operation */ -void requestSimIo(RIL_Token t, void *data, size_t datalen) +void ril_request_sim_io(RIL_Token t, void *data, size_t datalen) { const RIL_SIM_IO *sim_io; unsigned char message[262]; @@ -247,7 +264,7 @@ void requestSimIo(RIL_Token t, void *data, size_t datalen) hex2bin(sim_io->data, strlen(sim_io->data), rsim_payload); } - ipc_client_send(ipc_client, IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, (unsigned char*)&message, sizeof(message), getRequestId(t)); + ipc_fmt_send(IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, (unsigned char*)&message, sizeof(message), reqGetId(t)); } /** @@ -260,10 +277,10 @@ void requestSimIo(RIL_Token t, void *data, size_t datalen) * where it assumes all of the EF selection will be done by the * callee. */ -void respondSecRsimAccess(RIL_Token t, void *data, int length) +void ipc_sec_rsim_access(struct ipc_message_info *info) { - struct ipc_sec_rsim_access_response *rsim_resp = (struct ipc_sec_rsim_access_response*)data; - const unsigned char *data_ptr = ((unsigned char*)data + sizeof(*rsim_resp)); + struct ipc_sec_rsim_access_response *rsim_resp = (struct ipc_sec_rsim_access_response *) info->data; + const unsigned char *data_ptr = ((unsigned char *) info->data + sizeof(*rsim_resp)); char *sim_resp; RIL_SIM_IO_Response response; @@ -279,60 +296,12 @@ void respondSecRsimAccess(RIL_Token t, void *data, int length) response.simResponse[0] = '\0'; } - RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &response, sizeof(response)); free(response.simResponse); } /** - * In: RIL_REQUEST_GET_IMSI - * Get the SIM IMSI - * Only valid when radio state is "RADIO_STATE_SIM_READY" - * - * Out: IPC_MISC_ME_IMSI - * Requests ME's IMSI - */ -void requestIMSI(RIL_Token t) -{ - ipc_client_send_get(IPC_MISC_ME_IMSI, getRequestId(t)); -} - -/** - * In: IPC_MISC_ME_IMSI - * Provides ME's IMSI - * - * Out: RIL_REQUEST_GET_IMSI - * Get the SIM IMSI - * Only valid when radio state is "RADIO_STATE_SIM_READY" - */ -void respondIMSI(struct ipc_message_info *request) -{ - unsigned char *imsi_length; - char *imsi; - - if(request->length < 1) { - LOGE("%s: zero data length", __FUNCTION__); - RIL_onRequestComplete(getToken(request->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - - imsi_length = (unsigned char*)request->data; - - if(((int)request->length) < *imsi_length + 1) { - LOGE("%s: missing IMSI data", __FUNCTION__); - RIL_onRequestComplete(getToken(request->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - - /* Copy IMSI */ - imsi = (char*)malloc(*imsi_length+1); - memcpy(imsi, ((unsigned char*)request->data)+1, *imsi_length); - imsi[*imsi_length] = '\0'; - - RIL_onRequestComplete(getToken(request->aseq), RIL_E_SUCCESS, imsi, *imsi_length+1); -} - -/** * In: RIL_REQUEST_ENTER_SIM_PIN * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state * @@ -342,10 +311,10 @@ void respondIMSI(struct ipc_message_info *request) * Out: IPC_SEC_LOCK_INFO * Retrieves PIN1 lock status */ -void requestEnterSimPin(RIL_Token t, void *data, size_t datalen) +void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t datalen) { struct ipc_sec_pin_status_set pin_status; - char *pin = ((char**)data)[0]; + char *pin = ((char **) data)[0]; unsigned char buf[9]; /* 1. Send PIN */ @@ -356,16 +325,17 @@ void requestEnterSimPin(RIL_Token t, void *data, size_t datalen) ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, NULL); - ipc_client_send_set(IPC_SEC_PIN_STATUS, getRequestId(t), (unsigned char*)&pin_status, sizeof(pin_status)); + ipc_fmt_send_set(IPC_SEC_PIN_STATUS, reqGetId(t), (unsigned char *) &pin_status, sizeof(pin_status)); /* 2. Get lock status */ memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = IPC_SEC_PIN_TYPE_PIN1; - ipc_client_send(ipc_client, IPC_SEC_LOCK_INFO, IPC_TYPE_GET, buf, sizeof(buf), getRequestId(t)); + ipc_fmt_send(IPC_SEC_LOCK_INFO, IPC_TYPE_GET, buf, sizeof(buf), reqGetId(t)); } + /** * In: IPC_GEN_PHONE_RES * Provides result of IPC_SEC_PIN_STATUS SET @@ -373,15 +343,17 @@ void requestEnterSimPin(RIL_Token t, void *data, size_t datalen) * Out: RIL_REQUEST_ENTER_SIM_PIN * Returns PIN SIM unlock result */ -void respondSecPinStatus(struct ipc_message_info *request) +// FIXME: here, we're going to do that: +// do the pin status req, enqueue the token to gen phone res and use this custom function (dd possibility to use custom functions on return, not only return bare requests complete with dumb RIL_E_) +void ipc_sec_pin_status_res(struct ipc_message_info *info) { - struct ipc_gen_phone_res *gen_res = (struct ipc_gen_phone_res*)request->data; + struct ipc_gen_phone_res *gen_res = (struct ipc_gen_phone_res *) info->data; int attempts = -1; if(gen_res->code == 0x0010) { - RIL_onRequestComplete(getToken(request->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(int*)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(int*)); } else if(gen_res->code == 0x8000) { - RIL_onRequestComplete(getToken(request->aseq), RIL_E_SUCCESS, &attempts, sizeof(int*)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &attempts, sizeof(int*)); } else { LOGE("%s: unhandled code %04x", __FUNCTION__, gen_res->code); } @@ -391,14 +363,14 @@ void respondSecPinStatus(struct ipc_message_info *request) * In: IPC_SEC_LOCK_INFO * Provides number of retries left for a lock type */ -void respondLockInfo(struct ipc_message_info *request) +void ipc_sec_lock_info(struct ipc_message_info *info) { /* * FIXME: solid way of handling lockinfo and sim unlock response together * so we can return the number of attempts left in respondSecPinStatus */ int attempts; - struct ipc_sec_lock_info_response *lock_info = (struct ipc_sec_lock_info_response*)request->data; + struct ipc_sec_lock_info_response *lock_info = (struct ipc_sec_lock_info_response *) info->data; if(lock_info->type == IPC_SEC_PIN_TYPE_PIN1) { attempts = lock_info->attempts; @@ -414,7 +386,7 @@ void respondLockInfo(struct ipc_message_info *request) * * Out: IPC_SEC_PHONE_LOCK GET */ -void requestQueryFacilityLock(RIL_Token t, void *data, size_t datalen) +void ril_request_query_facility_lock(RIL_Token t, void *data, size_t datalen) { unsigned char lock_type; char *facility = ((char**)data)[0]; @@ -428,7 +400,7 @@ void requestQueryFacilityLock(RIL_Token t, void *data, size_t datalen) RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); } - ipc_client_send(ipc_client, IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, &lock_type, sizeof(lock_type), getRequestId(t)); + ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, &lock_type, sizeof(lock_type), reqGetId(t)); } /** @@ -437,14 +409,14 @@ void requestQueryFacilityLock(RIL_Token t, void *data, size_t datalen) * Out: RIL_REQUEST_QUERY_FACILITY_LOCK * Query the status of a facility lock state */ -void respondSecPhoneLock(struct ipc_message_info *request) +void ipc_sec_phone_lock(struct ipc_message_info *info) { int status; - struct ipc_sec_phone_lock_response *lock = (struct ipc_sec_phone_lock_response*)request->data; + struct ipc_sec_phone_lock_response *lock = (struct ipc_sec_phone_lock_response *) info->data; status = lock->status; - RIL_onRequestComplete(getToken(request->aseq), RIL_E_SUCCESS, &status, sizeof(int*)); + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &status, sizeof(int*)); } /** @@ -453,7 +425,7 @@ void respondSecPhoneLock(struct ipc_message_info *request) * * Out: IPC_SEC_PHONE_LOCK SET */ -void requestSetFacilityLock(RIL_Token t, void *data, size_t datalen) +void ril_request_set_facility_lock(RIL_Token t, void *data, size_t datalen) { unsigned char lock_type; char *facility = ((char**)data)[0]; @@ -467,5 +439,5 @@ void requestSetFacilityLock(RIL_Token t, void *data, size_t datalen) RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); } - ipc_client_send(ipc_client, IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, &lock_type, sizeof(lock_type), getRequestId(t)); + ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, &lock_type, sizeof(lock_type), reqGetId(t)); } @@ -1,35 +1,52 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #define LOG_TAG "RIL-SMS" #include <utils/Log.h> #include "samsung-ril.h" #include "util.h" -extern const struct RIL_Env *rilenv; -extern struct radio_state radio; -extern struct ipc_client *ipc_client; - -void respondSmsIncoming(RIL_Token t, void *data, int length) +void ipc_sms_incoming_msg(struct ipc_message_info *info) { - struct ipc_sms_incoming_msg *info = (struct ipc_sms_incoming_msg*)data; - unsigned char *pdu = ((unsigned char*)data + sizeof(struct ipc_sms_incoming_msg)); + struct ipc_sms_incoming_msg *msg = (struct ipc_sms_incoming_msg *) info->data; + unsigned char *pdu = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg)); - int resp_length = info->length * 2 + 1; - char *resp = (char*)malloc(resp_length); + int resp_length = msg->length * 2 + 1; + char *resp = (char *) malloc(resp_length); - bin2hex(pdu, info->length, resp); + bin2hex(pdu, msg->length, resp); LOGD("PDU string is '%s'\n", resp); - if(radio.msg_tpid_lock != 0) { + if(ril_state.msg_tpid_lock != 0) { LOGE("Another message is already waiting for ACK, aborting"); //FIXME: it would be cleaner to enqueue it goto exit; } - radio.msg_tpid_lock = info->msg_tpid; + ril_state.msg_tpid_lock = msg->msg_tpid; - if(info->type == IPC_SMS_TYPE_POINT_TO_POINT) { + if(msg->type == IPC_SMS_TYPE_POINT_TO_POINT) { RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS, resp, resp_length); - } else if(info->type == IPC_SMS_TYPE_STATUS_REPORT) { + } else if(msg->type == IPC_SMS_TYPE_STATUS_REPORT) { RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, resp, resp_length); } else { LOGE("%s: Unknown message type", __FUNCTION__); @@ -39,31 +56,64 @@ exit: free(resp); } -void requestSendSms(RIL_Token t, void *data, size_t datalen) +unsigned short sms_ack_error_ril2ipc(int success, int failcause) { - const char **request; - request = (char **) data; - int pdu_len = strlen(request[1]); + if(success) { + return IPC_SMS_ACK_NO_ERROR; + } else { + switch(failcause) { + case 0xD3: + return IPC_SMS_ACK_PDA_FULL_ERROR; + default: + return IPC_SMS_ACK_UNSPEC_ERROR; + } + } +} - /* We first need to get SMS SVC before sending the message */ +RIL_Errno sms_ack_error_ipc2ril(unsigned short error) +{ + switch(error) { + case IPC_SMS_ACK_NO_ERROR: + return RIL_E_SUCCESS; + default: + return RIL_E_GENERIC_FAILURE; + } +} - if(request[0] == NULL) { - LOGD("We have no SMSC, asking one before anything"); +/** + * In: RIL_REQUEST_SMS_ACKNOWLEDGE + * Acknowledge successful or failed receipt of SMS previously indicated + * via RIL_UNSOL_RESPONSE_NEW_SMS + * + * Out: IPC_SMS_DELIVER_REPORT + * Sends a SMS delivery report + */ +void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t datalen) +{ + struct ipc_sms_deliv_report_msg report_msg; + int success = ((int *)data)[0]; + int failcause = ((int *)data)[1]; - if(radio.tokens.send_sms != 0 && radio.msg_pdu != NULL) { - LOGE("Another message is being sent, aborting"); - //FIXME: it would be cleaner to enqueue it - } + if(ril_state.msg_tpid_lock == 0) { + LOGE("No stored msg_tpid, aborting\n"); + return; + } - radio.tokens.send_sms = t; - radio.msg_pdu = malloc(pdu_len); - memcpy(radio.msg_pdu, request[1], pdu_len); + report_msg.type = IPC_SMS_TYPE_STATUS_REPORT; + report_msg.error = sms_ack_error_ril2ipc(success, failcause); + report_msg.msg_tpid = ril_state.msg_tpid_lock; + report_msg.unk = 0; - ipc_client_send_get(IPC_SMS_SVC_CENTER_ADDR, getRequestId(t)); - - } else { - sms_send_msg(t, request[1], request[0]); - } + ril_state.msg_tpid_lock = 0; + + ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(struct ipc_sms_deliv_report_msg), reqGetId(t)); +} + +void ipc_sms_deliver_report(struct ipc_message_info *info) +{ + //FIXME: check it's alright from data (or not, no need to check the ACK of our ACK) + + RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, NULL, 0); } void sms_send_msg(RIL_Token t, char *pdu, char *smsc_string) @@ -102,24 +152,41 @@ void sms_send_msg(RIL_Token t, char *pdu, char *smsc_string) p += smsc_len; memcpy(p, decoded_pdu, pdu_len); - ipc_client_send(ipc_client, IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, getRequestId(t)); + ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, reqGetId(t)); /* Wait for ACK to return to RILJ */ - radio.tokens.send_sms = t; + ril_state.tokens.send_sms = t; free(decoded_pdu); free(data); } -void respondSmsSvcCenterAddr(RIL_Token t, void *data, size_t datalen) +void ril_request_send_sms(RIL_Token t, void *data, size_t datalen) { - if(radio.tokens.send_sms == t && radio.msg_pdu != NULL) { - sms_send_msg(t, radio.msg_pdu, data); + const char **request; + request = (char **) data; + int pdu_len = strlen(request[1]); + + /* We first need to get SMS SVC before sending the message */ - free(radio.msg_pdu); + if(request[0] == NULL) { + LOGD("We have no SMSC, asking one before anything"); + + if(ril_state.tokens.send_sms != 0 && ril_state.msg_pdu != NULL) { + LOGE("Another message is being sent, aborting"); + //FIXME: it would be cleaner to enqueue it + } + + ril_state.tokens.send_sms = t; + ril_state.msg_pdu = malloc(pdu_len); + memcpy(ril_state.msg_pdu, request[1], pdu_len); + + ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, reqGetId(t)); + + } else { + sms_send_msg(t, request[1], request[0]); } } - /** * In: RIL_REQUEST_SEND_SMS_EXPECT_MORE * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS, @@ -128,42 +195,30 @@ void respondSmsSvcCenterAddr(RIL_Token t, void *data, size_t datalen) * * Out: IPC_SMS_SEND_MSG */ -void requestSendSmsExpectMore(RIL_Token t, void *data, size_t datalen) +void ril_request_send_sms_expect_more(RIL_Token t, void *data, size_t datalen) { /* FIXME: We seriously need a decent queue here */ } -unsigned short sms_ack_error_ril2ipc(int success, int failcause) +void ipc_sms_svc_center_addr(struct ipc_message_info *info) { - if(success) { - return IPC_SMS_ACK_NO_ERROR; - } else { - switch(failcause) { - case 0xD3: - return IPC_SMS_ACK_PDA_FULL_ERROR; - default: - return IPC_SMS_ACK_UNSPEC_ERROR; - } - } -} + RIL_Token t = reqGetToken(info->aseq); -RIL_Errno sms_ack_error_ipc2ril(unsigned short error) -{ - switch(error) { - case IPC_SMS_ACK_NO_ERROR: - return RIL_E_SUCCESS; - default: - return RIL_E_GENERIC_FAILURE; + if(ril_state.tokens.send_sms == t && ril_state.msg_pdu != NULL) { + sms_send_msg(t, ril_state.msg_pdu, info->data); + + free(ril_state.msg_pdu); } } -void respondSmsSendMsg(RIL_Token t, void *data, size_t datalen) +void ipc_sms_send_msg(struct ipc_message_info *info) { - struct ipc_sms_deliv_report_msg *report_msg = data; + struct ipc_sms_deliv_report_msg *report_msg = info->data; RIL_Errno ril_ack_err; + RIL_Token t = reqGetToken(info->aseq); - if(radio.tokens.send_sms != t) { + if(ril_state.tokens.send_sms != t) { LOGE("Wrong token to ACK"); } @@ -171,53 +226,18 @@ void respondSmsSendMsg(RIL_Token t, void *data, size_t datalen) ril_ack_err = sms_ack_error_ipc2ril(report_msg->error); - radio.tokens.send_sms = 0; + ril_state.tokens.send_sms = 0; + //messageRef = tpid, it's not NULL ↓ RIL_onRequestComplete(t, ril_ack_err, NULL, 0); } -/** - * In: RIL_REQUEST_SMS_ACKNOWLEDGE - * Acknowledge successful or failed receipt of SMS previously indicated - * via RIL_UNSOL_RESPONSE_NEW_SMS - * - * Out: IPC_SMS_DELIVER_REPORT - * Sends a SMS delivery report - */ -void requestSmsAcknowledge(RIL_Token t, void *data, size_t datalen) -{ - struct ipc_sms_deliv_report_msg report_msg; - int success = ((int *)data)[0]; - int failcause = ((int *)data)[1]; - - if(radio.msg_tpid_lock == 0) { - LOGE("No stored msg_tpid, aborting\n"); - return; - } - - report_msg.type = IPC_SMS_TYPE_STATUS_REPORT; - report_msg.error = sms_ack_error_ril2ipc(success, failcause); - report_msg.msg_tpid = radio.msg_tpid_lock; - report_msg.unk = 0; - - radio.msg_tpid_lock = 0; - - ipc_client_send(ipc_client, IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(struct ipc_sms_deliv_report_msg), getRequestId(t)); -} - -void respondSmsDeliverReport(RIL_Token t, void *data, size_t datalen) -{ - //FIXME: check it's alright from data (or not, no need to check the ACK of our ACK) - - RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -void respondSmsDeviceReady(RIL_Token t, struct ipc_message_info *info) +void ipc_sms_device_ready(struct ipc_message_info *info) { - if(radio.radio_state == RADIO_STATE_SIM_READY) { - ipc_client_send(ipc_client, IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, getRequestId(t)); + if(ril_state.radio_state == RADIO_STATE_SIM_READY) { + ipc_fmt_send(IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, info->aseq); } - RadioTokensCheck(); + ril_tokens_check(); } @@ -0,0 +1,34 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#define LOG_TAG "RIL-SND" +#include <utils/Log.h> + +#include "samsung-ril.h" +#include "util.h" + +void srs_snd_set_call_clock_sync(struct srs_message *message) +{ + unsigned char data = *((unsigned char *) message->data); + LOGE("SetCallClockSync data is 0x%x\n", data); + + ipc_fmt_send(IPC_SND_CLOCK_CTRL, IPC_TYPE_EXEC, &data, sizeof(data), reqIdNew()); +} diff --git a/socket.c b/socket.c deleted file mode 100644 index 7c0f8ed..0000000 --- a/socket.c +++ /dev/null @@ -1,148 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> - -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/select.h> - -#include <arpa/inet.h> -#include <netinet/in.h> -#include <cutils/sockets.h> - -#include <cutils/log.h> - -#include <samsung-ril-socket.h> -#include "socket.h" - -struct srs_server *srs_server_new(void) -{ - struct srs_server *srs_server; - - srs_server = malloc(sizeof(struct srs_server)); - memset(srs_server, 0, sizeof(struct srs_server)); - srs_server->server_fd = -1; - srs_server->client_fd = -1; - - return srs_server; -} - -int srs_server_send_message(struct srs_server *srs_server, struct srs_message *message) -{ - fd_set fds; - - struct srs_header header; - void *data; - - header.length = message->data_len + sizeof(header); - header.group = SRS_GROUP(message->command); - header.index = SRS_INDEX(message->command); - header.msg_id = message->msg_id; - - data = malloc(header.length); - memset(data, 0, header.length); - - memcpy(data, &header, sizeof(header)); - memcpy((void *) (data + sizeof(header)), message->data, message->data_len); - - FD_ZERO(&fds); - FD_SET(srs_server->client_fd, &fds); - - select(FD_SETSIZE, NULL, &fds, NULL, NULL); - - write(srs_server->client_fd, data, header.length); - - //FIXME: can we free? - - return 0; -} - -int srs_server_send(struct srs_server *srs_server, unsigned short command, void *data, int data_len, unsigned msg_id) -{ - struct srs_message message; - int rc; - - message.command = command; - message.data = data; - message.data_len = data_len; - message.msg_id = msg_id; - - rc = srs_server_send_message(srs_server, &message); - - return rc; -} - -int srs_server_recv(struct srs_server *srs_server, struct srs_message *message) -{ - void *raw_data = malloc(SRS_DATA_MAX_SIZE); - struct srs_header *header; - int rc; - - rc = read(srs_server->client_fd, raw_data, SRS_DATA_MAX_SIZE); - if(rc < sizeof(struct srs_header)) { - return -1; - } - - header = raw_data; - - message->command = SRS_COMMAND(header); - message->msg_id = header->msg_id; - message->data_len = header->length - sizeof(struct srs_header); - message->data = malloc(message->data_len); - - memcpy(message->data, raw_data + sizeof(struct srs_header), message->data_len); - - free(raw_data); - - return 0; -} - -int srs_server_accept(struct srs_server *srs_server) -{ - int client_fd = -1; - struct sockaddr_un client_addr; - int client_addr_len; - - if(srs_server->client_fd > 0) { - return 0; - } - - client_fd = accept(srs_server->server_fd, (struct sockaddr_un *) &client_addr, &client_addr_len); - - if(client_fd > 0) { - srs_server->client_fd = client_fd; - srs_server->client_addr = client_addr; - srs_server->client_addr_len = client_addr_len; - - return 0; - } - - return -1; -} - -int srs_server_open(struct srs_server *srs_server) -{ - int server_fd = -1; - - int t = 0; - - while(t < 5) { - unlink(SRS_SOCKET_NAME); - server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); - - if(server_fd > 0) - break; - - t++; - } - - if(server_fd < 0) - return -1; - - srs_server->server_fd = server_fd; - - return 0; -} diff --git a/socket.h b/socket.h deleted file mode 100644 index 0277c00..0000000 --- a/socket.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _SOCKET_H_ -#define _SOCKET_H_ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <arpa/inet.h> -#include <netinet/in.h> - -struct srs_server { - int server_fd; - int client_fd; - struct sockaddr_un client_addr; - int client_addr_len; -}; - -struct srs_server *srs_server_new(void); -int srs_server_send(struct srs_server *srs_server, unsigned short command, void *data, int data_len, unsigned msg_id); -int srs_server_recv(struct srs_server *srs_server, struct srs_message *message); -int srs_server_accept(struct srs_server *srs_server); -int srs_server_open(struct srs_server *srs_server); - -#endif @@ -0,0 +1,291 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/select.h> + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <cutils/sockets.h> + +#define LOG_TAG "RIL-SRS" +#include <utils/Log.h> + +#include "samsung-ril.h" +#include "util.h" + +struct srs_server *srs_server_new(void) +{ + struct srs_server *srs_server; + + srs_server = malloc(sizeof(struct srs_server)); + memset(srs_server, 0, sizeof(struct srs_server)); + srs_server->server_fd = -1; + srs_server->client_fd = -1; + + return srs_server; +} + +void srs_server_free(struct srs_server *srs_server) +{ + if(srs_server == NULL) + return; + + free(srs_server); +} + +int srs_server_send_message(struct srs_server *srs_server, struct srs_message *message) +{ + fd_set fds; + + struct srs_header header; + void *data; + + header.length = message->data_len + sizeof(header); + header.group = SRS_GROUP(message->command); + header.index = SRS_INDEX(message->command); + + data = malloc(header.length); + memset(data, 0, header.length); + + memcpy(data, &header, sizeof(header)); + memcpy((void *) (data + sizeof(header)), message->data, message->data_len); + + FD_ZERO(&fds); + FD_SET(srs_server->client_fd, &fds); + + select(FD_SETSIZE, NULL, &fds, NULL, NULL); + + write(srs_server->client_fd, data, header.length); + + free(data); + + return 0; +} + +int srs_server_send(unsigned short command, void *data, int data_len) +{ + struct srs_server *srs_server; + struct srs_message message; + int rc; + + srs_server = (struct srs_server *) (srs_client->object); + + message.command = command; + message.data = data; + message.data_len = data_len; + + rc = srs_server_send_message(srs_server, &message); + + return rc; +} + +int srs_server_recv(struct srs_server *srs_server, struct srs_message *message) +{ + void *raw_data = malloc(SRS_DATA_MAX_SIZE); + struct srs_header *header; + int rc; + + rc = read(srs_server->client_fd, raw_data, SRS_DATA_MAX_SIZE); + if(rc < sizeof(struct srs_header)) { + return -1; + } + + header = raw_data; + + message->command = SRS_COMMAND(header); + message->data_len = header->length - sizeof(struct srs_header); + message->data = malloc(message->data_len); + + memcpy(message->data, raw_data + sizeof(struct srs_header), message->data_len); + + free(raw_data); + + return 0; +} + +int srs_server_accept(struct srs_server *srs_server) +{ + int client_fd = -1; + struct sockaddr_un client_addr; + int client_addr_len; + + if(srs_server->client_fd > 0) { + return 0; + } + + client_fd = accept(srs_server->server_fd, (struct sockaddr_un *) &client_addr, &client_addr_len); + + if(client_fd > 0) { + srs_server->client_fd = client_fd; + srs_server->client_addr = client_addr; + srs_server->client_addr_len = client_addr_len; + + return 0; + } + + return -1; +} + +void srs_control_ping(struct srs_message *message) +{ + int caffe; + + if(message->data == NULL) + return; + + caffe=*((int *) message->data); + + if(caffe == SRS_CONTROL_CAFFE) { + srs_server_send(SRS_CONTROL_PING, &caffe, sizeof(caffe)); + } +} + +int srs_server_open(struct srs_server *srs_server) +{ + int server_fd = -1; + + int t = 0; + + while(t < 5) { + unlink(SRS_SOCKET_NAME); + server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); + + if(server_fd > 0) + break; + + t++; + } + + if(server_fd < 0) + return -1; + + srs_server->server_fd = server_fd; + + return 0; +} + +int srs_read_loop(struct ril_client *client) +{ + struct srs_server *srs_server; + struct srs_message srs_message; + fd_set fds; + int rc; + + if(client == NULL) { + LOGE("client is NULL, aborting!"); + return -1; + } + + if(client->object == NULL) { + LOGE("client object is NULL, aborting!"); + return -1; + } + + srs_server = (struct srs_server *) client->object; + + while(1) { + if(srs_server->server_fd < 0) { + LOGE("SRS client server_fd is negative, aborting!"); + return -1; + } + + rc = srs_server_accept(srs_server); + + LOGE("SRS server accept!"); + + FD_ZERO(&fds); + FD_SET(srs_server->client_fd, &fds); + + while(1) { + if(srs_server->client_fd < 0) + break; + + select(FD_SETSIZE, &fds, NULL, NULL, NULL); + + if(FD_ISSET(srs_server->client_fd, &fds)) { + if(srs_server_recv(srs_server, &srs_message) < 0) { + LOGE("SRS recv failed, aborting!"); + break; + } + + LOGD("SRS recv: command=%d data_len=%d", srs_message.command, srs_message.data_len); + hex_dump(srs_message.data, srs_message.data_len); + + srs_dispatch(&srs_message); + + if(srs_message.data != NULL) + free(srs_message.data); + } + } + + if(srs_server->client_fd > 0) { + close(srs_server->client_fd); + srs_server->client_fd = -1; + } + + LOGE("SRS server client ended!"); + } + + return 0; +} + +int srs_create(struct ril_client *client) +{ + struct srs_server *srs_server; + + LOGD("Creating new SRS client"); + + srs_server = srs_server_new(); + client->object = (void *) srs_server; + + if(srs_server_open(srs_server) < 0) { + LOGE("%s: samsung-ril-socket server open failed", __FUNCTION__); + return -1; + } + + return 0; +} + +int srs_destroy(struct ril_client *client) +{ + struct srs_server *srs_server = (struct srs_server *) client->object; + + if(srs_server == NULL) + return 0; + + if(srs_server->client_fd) + close(srs_server->client_fd); + + close(srs_server->server_fd); + + srs_server_free(srs_server); + + return 0; +} + +struct ril_client_funcs srs_client_funcs = { + .create = srs_create, + .destroy = srs_destroy, + .read_loop = srs_read_loop, +}; @@ -0,0 +1,50 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef _SRS_H_ +#define _SRS_H_ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <samsung-ril-socket.h> + +struct srs_server { + int server_fd; + int client_fd; + struct sockaddr_un client_addr; + int client_addr_len; +}; + +extern struct ril_client_funcs srs_client_funcs; + +struct srs_server *srs_server_new(void); +int srs_server_send(unsigned short command, void *data, int data_len); +int srs_server_recv(struct srs_server *srs_server, struct srs_message *message); +int srs_server_accept(struct srs_server *srs_server); +int srs_server_open(struct srs_server *srs_server); + +void srs_control_ping(struct srs_message *message); + +#endif @@ -1,3 +1,23 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + #include <stdio.h> #include <string.h> @@ -63,3 +83,57 @@ void bin2hex(const unsigned char *data, int length, char *buf) *p = '\0'; } + +void hex_dump(void *data, int size) +{ + /* dumps size bytes of *data to stdout. Looks like: + * [0000] 75 6E 6B 6E 6F 77 6E 20 + * 30 FF 00 00 00 00 39 00 unknown 0.....9. + * (in a single line of course) + */ + + unsigned char *p = data; + unsigned char c; + int n; + char bytestr[4] = {0}; + char addrstr[10] = {0}; + char hexstr[ 16*3 + 5] = {0}; + char charstr[16*1 + 5] = {0}; + for(n=1;n<=size;n++) { + if (n%16 == 1) { + /* store address for this line */ + snprintf(addrstr, sizeof(addrstr), "%.4x", + ((unsigned int)p-(unsigned int)data) ); + } + + c = *p; + if (isalnum(c) == 0) { + c = '.'; + } + + /* store hex str (for left side) */ + snprintf(bytestr, sizeof(bytestr), "%02X ", *p); + strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); + + /* store char str (for right side) */ + snprintf(bytestr, sizeof(bytestr), "%c", c); + strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); + + if(n%16 == 0) { + /* line completed */ + LOGD("[%4.4s] %-50.50s %s", addrstr, hexstr, charstr); + hexstr[0] = 0; + charstr[0] = 0; + } else if(n%8 == 0) { + /* half line: add whitespaces */ + strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); + strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); + } + p++; /* next byte */ + } + + if (strlen(hexstr) > 0) { + /* print rest of buffer if not empty */ + LOGD("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); + } +} @@ -1,2 +1,28 @@ +/** + * This file is part of samsung-ril. + * + * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com> + * + * samsung-ril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * samsung-ril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef _SAMSUNG_RIL_UTIL_H_ +#define _SAMSUNG_RIL_UTIL_H_ + void bin2hex(const unsigned char *data, int length, char *buf); void hex2bin(const char *data, int length, unsigned char *buf); +void hex_dump(void *data, int size); + +#endif |