aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--samsung-ipc/device/aries/aries_ipc.c944
-rw-r--r--samsung-ipc/device/aries/aries_ipc.h (renamed from samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.h)42
-rw-r--r--samsung-ipc/device/aries/onedram.h30
-rw-r--r--samsung-ipc/device/aries/phonet.h62
-rw-r--r--samsung-ipc/device/aries/sipc4.h256
-rw-r--r--samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c644
-rw-r--r--samsung-ipc/device/galaxysmtd/galaxysmtd_modem_ctl.h44
-rw-r--r--samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.c356
-rw-r--r--samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.h41
9 files changed, 1313 insertions, 1106 deletions
diff --git a/samsung-ipc/device/aries/aries_ipc.c b/samsung-ipc/device/aries/aries_ipc.c
new file mode 100644
index 0000000..92ab454
--- /dev/null
+++ b/samsung-ipc/device/aries/aries_ipc.c
@@ -0,0 +1,944 @@
+/**
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
+ * Joerie de Gram <j.de.gram@gmail.com>
+ * Simon Busch <morphis@gravedo.de>
+ * Igor Almeida <igor.contato@gmail.com>
+ *
+ * libsamsung-ipc 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.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <linux/netlink.h>
+#include <net/if.h>
+#include <asm/types.h>
+#include <mtd/mtd-abi.h>
+#include <assert.h>
+
+#include <radio.h>
+
+#include "aries_ipc.h"
+#include "ipc_private.h"
+#include "sipc4.h"
+#include "onedram.h"
+#include "phonet.h"
+
+int phonet_iface_ifdown(void)
+{
+ struct ifreq ifr;
+ int fd;
+ int rc;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, PHONET_IFACE, IFNAMSIZ);
+
+ fd = socket(AF_PHONET, SOCK_DGRAM, 0);
+
+ rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ if(rc < 0)
+ return -1;
+
+ ifr.ifr_flags = (ifr.ifr_flags & (~IFF_UP));
+
+ rc = ioctl(fd, SIOCSIFFLAGS, &ifr);
+ if(rc < 0)
+ return -1;
+
+ close(fd);
+
+ return 0;
+}
+
+int phonet_iface_ifup(void)
+{
+ struct ifreq ifr;
+ int fd;
+ int rc;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, PHONET_IFACE, IFNAMSIZ);
+
+ fd = socket(AF_PHONET, SOCK_DGRAM, 0);
+
+ rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ if(rc < 0)
+ return -1;
+
+ ifr.ifr_flags |= IFF_UP;
+
+ rc = ioctl(fd, SIOCSIFFLAGS, &ifr);
+ if(rc < 0)
+ return -1;
+
+ close(fd);
+
+ return 0;
+}
+
+int aries_modem_bootstrap(struct ipc_client *client)
+{
+ int s3c2410_serial3_fd = -1;
+ int onedram_fd = -1;
+
+ /* Control variables. */
+ int boot_tries_count = 0;
+ int rc = 0;
+
+ /* Boot variables */
+ uint8_t *radio_img_p = NULL;
+ uint32_t onedram_data = 0;
+ uint8_t bootcore_version = 0;
+ uint8_t info_size = 0;
+ uint8_t crc_byte = 0;
+ int block_size = 0;
+
+ /* s3c2410 serial setup variables. */
+ struct termios termios;
+ int serial;
+
+ /* fds maniplation variables */
+ struct timeval timeout;
+ fd_set fds;
+
+ /* nv_data variables */
+ void *nv_data_p;
+ void *onedram_p;
+
+ /* General purpose variables. */
+ uint8_t data;
+ uint16_t data_16;
+ uint8_t *data_p;
+ int i;
+
+ ipc_client_log(client, "aries_ipc_bootstrap: enter");
+
+boot_loop_start:
+ if(boot_tries_count > 5)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: boot has failed too many times.");
+ goto error;
+ }
+
+ /* Read the radio.img image. */
+ ipc_client_log(client, "aries_ipc_bootstrap: reading radio image");
+ radio_img_p = ipc_mtd_read(client, "/dev/block/bml12", RADIO_IMG_READ_SIZE, RADIO_IMG_READ_SIZE);
+ ipc_client_log(client, "aries_ipc_bootstrap: radio image read");
+
+ ipc_client_log(client, "aries_ipc_bootstrap: open onedram");
+ onedram_fd=open("/dev/onedram", O_RDWR);
+ if(onedram_fd < 0)
+ goto error_loop;
+
+ /* Reset the modem before init to send the first part of modem.img. */
+ ipc_client_log(client, "aries_ipc_bootstrap: turning %s iface down", PHONET_IFACE);
+ rc = phonet_iface_ifdown();
+ if(rc < 0)
+ goto error;
+
+ ipc_client_power_off(client);
+ ipc_client_log(client, "aries_ipc_bootstrap: sent PHONE \"off\" command");
+ usleep(1000);
+
+ ipc_client_power_on(client);
+ ipc_client_log(client, "aries_ipc_bootstrap: sent PHONE \"on\" command");
+ usleep(200000);
+
+ ipc_client_log(client, "aries_ipc_bootstrap: open s3c2410_serial3");
+ s3c2410_serial3_fd=open("/dev/s3c2410_serial3", O_RDWR);
+ if(s3c2410_serial3_fd < 0)
+ goto error_loop;
+
+ /* Setup the s3c2410 serial. */
+ ipc_client_log(client, "aries_ipc_bootstrap: setup s3c2410_serial3");
+ tcgetattr(s3c2410_serial3_fd, &termios);
+
+ cfmakeraw(&termios);
+ cfsetispeed(&termios, B115200);
+ cfsetospeed(&termios, B115200);
+
+ tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios);
+
+ /* Send 'AT' in ASCII. */
+ ipc_client_log(client, "aries_ipc_bootstrap: sending AT in ASCII");
+ for(i=0 ; i < 20 ; i++)
+ {
+ rc = write(s3c2410_serial3_fd, "AT", 2);
+ usleep(50000);
+ }
+ ipc_client_log(client, "aries_ipc_bootstrap: sending AT in ASCII done");
+
+ usleep(50000); //FIXME
+
+ /* Write the first part of modem.img. */
+ FD_ZERO(&fds);
+ FD_SET(s3c2410_serial3_fd, &fds);
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ /* Get and check bootcore version. */
+ read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version));
+ ipc_client_log(client, "aries_ipc_bootstrap: got bootcore version: 0x%x", bootcore_version);
+
+ if(bootcore_version != BOOTCORE_VERSION)
+ goto error_loop;
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ /* Get info_size. */
+ read(s3c2410_serial3_fd, &info_size, sizeof(info_size));
+ ipc_client_log(client, "aries_ipc_bootstrap: got info_size: 0x%x", info_size);
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ /* Send PSI magic. */
+ data=PSI_MAGIC;
+ write(s3c2410_serial3_fd, &data, sizeof(data));
+ ipc_client_log(client, "aries_ipc_bootstrap: sent PSI_MAGIC (0x%x)", PSI_MAGIC);
+
+ /* Send PSI data len. */
+ data_16=PSI_DATA_LEN;
+ data_p=(uint8_t *)&data_16;
+
+ for(i=0 ; i < 2 ; i++)
+ {
+ write(s3c2410_serial3_fd, data_p, 1);
+ data_p++;
+ }
+ ipc_client_log(client, "aries_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)", PSI_DATA_LEN);
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ data_p=radio_img_p;
+
+ ipc_client_log(client, "aries_ipc_bootstrap: sending the first part of radio.img");
+
+ for(i=0 ; i < PSI_DATA_LEN ; i++)
+ {
+ if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ write(s3c2410_serial3_fd, data_p, 1);
+ crc_byte=crc_byte ^ *data_p;
+
+ data_p++;
+ }
+
+ ipc_client_log(client, "aries_ipc_bootstrap: first part of radio.img sent; crc_byte is 0x%x", crc_byte);
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));
+
+ ipc_client_log(client, "aries_ipc_bootstrap: crc_byte sent");
+
+ data = 0;
+ for(i = 0 ; data != 0x01 ; i++)
+ {
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ read(s3c2410_serial3_fd, &data, sizeof(data));
+
+ if(i > 50)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: fairly too much attempts to get ACK");
+ goto error_loop;
+ }
+ }
+
+ ipc_client_log(client, "aries_ipc_bootstrap: close s3c2410_serial3");
+ close(s3c2410_serial3_fd);
+
+ FD_ZERO(&fds);
+ FD_SET(onedram_fd, &fds);
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ ipc_client_log(client, "aries_ipc_bootstrap: wait for 0x12341234 from onedram");
+ if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ read(onedram_fd, &onedram_data, sizeof(onedram_data));
+
+ if(onedram_data != ONEDRAM_INIT_READ)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: wrong onedram init magic (got 0x%04x)", onedram_data);
+ goto error_loop;
+ }
+
+ ipc_client_log(client, "aries_ipc_bootstrap: got 0x%04x", onedram_data);
+
+ ipc_client_log(client, "aries_ipc_bootstrap: writing the rest of modem.img to onedram.");
+
+ /* Pointer to the remaining part of radio.img. */
+ data_p=radio_img_p + PSI_DATA_LEN;
+
+ onedram_p = mmap(NULL, ONENAND_MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, onedram_fd, 0);
+
+ if(onedram_p == NULL || onedram_p < 0 || onedram_p == 0xffffffff)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: could not map onedram to memory");
+ goto error_loop;
+ }
+
+ // it sometimes hangs here
+
+ memcpy(onedram_p, data_p, RADIO_IMG_READ_SIZE - PSI_DATA_LEN);
+
+ free(radio_img_p);
+
+ /* nv_data part. */
+
+ /* Check if all the nv_data files are ok. */
+ nv_data_check(client);
+
+ /* Check if the MD5 is ok. */
+ nv_data_md5_check(client);
+
+ /* Write nv_data.bin to modem_ctl. */
+ ipc_client_log(client, "aries_ipc_bootstrap: write nv_data to onedram");
+
+ nv_data_p = ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, 1024);
+ if (nv_data_p == NULL)
+ goto error;
+ data_p = nv_data_p;
+
+ memcpy(onedram_p + RADIO_IMG_MAX_SIZE, data_p, NV_DATA_SIZE);
+
+ free(nv_data_p);
+
+ munmap(onedram_p, ONENAND_MAP_SIZE);
+
+ if(ioctl(onedram_fd, ONEDRAM_REL_SEM) < 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: ONEDRAM_REL_SEM ioctl on onedram failed");
+ goto error_loop;
+ }
+
+ onedram_data = ONEDRAM_DEINIT_CMD;
+
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+
+ ipc_client_log(client, "aries_ipc_bootstrap: send 0x%04x", onedram_data);
+ write(onedram_fd, &onedram_data, sizeof(onedram_data));
+
+ if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ goto error_loop;
+ }
+
+ read(onedram_fd, &onedram_data, sizeof(onedram_data));
+
+ if(onedram_data != ONEDRAM_DEINIT_READ)
+ {
+ ipc_client_log(client, "aries_ipc_bootstrap: wrong onedram deinit magic (got 0x%04x)", onedram_data);
+ goto error_loop;
+ }
+
+ ipc_client_log(client, "aries_ipc_bootstrap: got 0x%04x", onedram_data);
+
+ close(onedram_fd);
+
+ rc = 0;
+ goto exit;
+
+error_loop:
+ ipc_client_log(client, "aries_ipc_bootstrap: something went wrong");
+ boot_tries_count++;
+ sleep(2);
+
+ goto boot_loop_start;
+
+error:
+ ipc_client_log(client, "aries_ipc_bootstrap: something went wrong");
+ rc = -1;
+exit:
+ ipc_client_log(client, "aries_ipc_bootstrap: exit");
+ return rc;
+}
+
+int aries_ipc_fmt_client_send(struct ipc_client *client, struct ipc_message_info *request)
+{
+ struct ipc_header reqhdr;
+ void *data;
+ int rc = 0;
+
+ reqhdr.mseq = request->mseq;
+ reqhdr.aseq = request->aseq;
+ reqhdr.group = request->group;
+ reqhdr.index = request->index;
+ reqhdr.type = request->type;
+ reqhdr.length = (uint16_t) (request->length + sizeof(struct ipc_header));
+
+ data = malloc(reqhdr.length);
+
+ memcpy(data, &reqhdr, sizeof(struct ipc_header));
+ memcpy((unsigned char *) (data + sizeof(struct ipc_header)), request->data, request->length);
+
+ assert(client->handlers->write != NULL);
+
+ ipc_client_log(client, "aries_ipc_fmt_client_send: SEND FMT!");
+ ipc_client_log(client, "aries_ipc_fmt_client_send: IPC request (mseq=0x%02x command=%s (0x%04x) type=%s)",
+ request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request), ipc_request_type_to_str(request->type));
+
+#ifdef DEBUG
+ if(request->length > 0)
+ {
+ ipc_client_log(client, "==== FMT DATA DUMP ====");
+ ipc_hex_dump(client, (void *) request->data, request->length);
+ }
+#endif
+
+ ipc_client_log(client, "");
+
+ rc = client->handlers->write(data, reqhdr.length, client->handlers->write_data);
+ return rc;
+}
+
+int aries_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_info *request)
+{
+ struct rfs_hdr *rfs_hdr;
+ void *data;
+ int rc = 0;
+
+ data = malloc(request->length + sizeof(struct rfs_hdr));
+ memset(data, 0, request->length + sizeof(struct rfs_hdr));
+
+ rfs_hdr = (struct rfs_hdr *) data;
+
+ rfs_hdr->id = request->mseq;
+ rfs_hdr->cmd = request->index;
+ rfs_hdr->len = request->length + sizeof(struct rfs_hdr);
+
+ memcpy((void *) (data + sizeof(struct rfs_hdr)), request->data, request->length);
+
+ assert(client->handlers->write != NULL);
+
+ ipc_client_log(client, "aries_ipc_rfs_client_send: SEND RFS (id=%d cmd=%d len=%d)!", rfs_hdr->id, rfs_hdr->cmd, rfs_hdr->len);
+ ipc_client_log(client, "aries_ipc_rfs_client_send: IPC request (mseq=0x%02x command=%s (0x%04x))",
+ request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request));
+
+#ifdef DEBUG
+ if(request->length > 0)
+ {
+ ipc_client_log(client, "==== RFS DATA DUMP ====");
+ ipc_hex_dump(client, (void *) (data + sizeof(struct rfs_hdr)), request->length);
+ }
+#endif
+
+ ipc_client_log(client, "");
+
+ rc = client->handlers->write((uint8_t*) data, rfs_hdr->len, client->handlers->write_data);
+ return rc;
+}
+
+int aries_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response)
+{
+ struct ipc_header *resphdr;
+ void *data;
+ int bread = 0;
+
+ data = malloc(MAX_MODEM_DATA_SIZE);
+ memset(data, 0, MAX_MODEM_DATA_SIZE);
+
+ memset(response, 0, sizeof(struct ipc_message_info));
+
+ assert(client->handlers->read != NULL);
+ bread = client->handlers->read((uint8_t*) data, MAX_MODEM_DATA_SIZE, client->handlers->read_data);
+
+ if (bread < 0)
+ {
+ ipc_client_log(client, "aries_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!");
+ return -1;
+ }
+
+ if(data == NULL)
+ {
+ ipc_client_log(client, "aries_ipc_fmt_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
+ return -1;
+ }
+
+ resphdr = (struct ipc_header *) data;
+
+ response->mseq = resphdr->mseq;
+ response->aseq = resphdr->aseq;
+ response->group = resphdr->group;
+ response->index = resphdr->index;
+ response->type = resphdr->type;
+ response->length = resphdr->length - sizeof(struct ipc_header);
+ response->data = NULL;
+
+ ipc_client_log(client, "aries_ipc_fmt_client_recv: RECV FMT!");
+ ipc_client_log(client, "aries_ipc_fmt_client_recv: IPC response (aseq=0x%02x command=%s (0x%04x) type=%s)",
+ response->aseq, ipc_command_to_str(IPC_COMMAND(response)), IPC_COMMAND(response), ipc_response_type_to_str(response->type));
+
+ if(response->length > 0)
+ {
+#ifdef DEBUG
+ ipc_client_log(client, "==== FMT DATA DUMP ====");
+ ipc_hex_dump(client, (void *) (data + sizeof(struct ipc_header)), response->length);
+#endif
+ response->data = malloc(response->length);
+ memcpy(response->data, (uint8_t *) data + sizeof(struct ipc_header), response->length);
+ }
+
+ free(data);
+
+ ipc_client_log(client, "");
+
+ return 0;
+}
+
+int aries_ipc_rfs_client_recv(struct ipc_client *client, struct ipc_message_info *response)
+{
+ void *data;
+ int bread = 0;
+ struct rfs_hdr *rfs_hdr;
+
+ data = malloc(MAX_MODEM_DATA_SIZE);
+ memset(data, 0, MAX_MODEM_DATA_SIZE);
+
+ memset(response, 0, sizeof(struct ipc_message_info));
+
+ assert(client->handlers->read != NULL);
+ bread = client->handlers->read((uint8_t*) data, MAX_MODEM_DATA_SIZE, client->handlers->read_data);
+ if (bread < 0)
+ {
+ ipc_client_log(client, "aries_ipc_rfs_client_recv: can't receive enough bytes from modem to process incoming response!");
+ return -1;
+ }
+
+ rfs_hdr = (struct rfs_hdr *) data;
+
+ if(rfs_hdr->len <= 0 || rfs_hdr->len >= MAX_MODEM_DATA_SIZE || data == NULL)
+ {
+ ipc_client_log(client, "aries_ipc_rfs_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
+ return -1;
+ }
+
+ response->mseq = 0;
+ response->aseq = rfs_hdr->id;
+ response->group = IPC_GROUP_RFS;
+ response->index = rfs_hdr->cmd;
+ response->type = 0;
+ response->length = rfs_hdr->len - sizeof(struct rfs_hdr);
+ response->data = NULL;
+
+ ipc_client_log(client, "aries_ipc_rfs_client_recv: RECV RFS (id=%d cmd=%d len=%d)!", rfs_hdr->id, rfs_hdr->cmd, rfs_hdr->len - sizeof(struct rfs_hdr));
+ ipc_client_log(client, "aries_ipc_rfs_client_recv: IPC response (aseq=0x%02x command=%s (0x%04x))",
+ response->mseq, ipc_command_to_str(IPC_COMMAND(response)), IPC_COMMAND(response));
+
+ if(response->length > 0)
+ {
+#ifdef DEBUG
+ ipc_client_log(client, "==== RFS DATA DUMP ====");
+ ipc_hex_dump(client, (void *) (data + sizeof(struct rfs_hdr)), response->length);
+#endif
+ response->data = malloc(response->length);
+ memcpy(response->data, (uint8_t *) (data + sizeof(struct rfs_hdr)), response->length);
+ }
+
+ free(data);
+
+ ipc_client_log(client, "");
+
+ return 0;
+}
+
+int aries_ipc_open(void *data, unsigned int size, void *io_data)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+ struct sockaddr_pn *spn;
+ struct ifreq ifr;
+
+ int type = *((int *) data);
+
+ int reuse;
+ int socket_rfs_magic;
+
+ int fd = -1;
+ int rc;
+
+ if(io_data == NULL)
+ goto error;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+ spn = common_data->spn;
+
+ memset(&ifr, 0, sizeof(ifr));
+ memset(ifr.ifr_name, 0, IFNAMSIZ);
+ memset(spn, 0, sizeof(struct sockaddr_pn));
+
+ strncpy(ifr.ifr_name, PHONET_IFACE, IFNAMSIZ);
+
+ spn->spn_family = AF_PHONET;
+ spn->spn_dev = 0;
+
+ switch(type)
+ {
+ case IPC_CLIENT_TYPE_FMT:
+ spn->spn_resource = PHONET_SPN_RES_FMT;
+ break;
+ case IPC_CLIENT_TYPE_RFS:
+ spn->spn_resource = PHONET_SPN_RES_RFS;
+ break;
+ default:
+ break;
+ }
+
+ fd = socket(AF_PHONET, SOCK_DGRAM, 0);
+ if(fd < 0)
+ return -1;
+
+ rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifr.ifr_name, IFNAMSIZ);
+ if(rc < 0)
+ goto error;
+
+ rc = ioctl(fd, SIOCGIFINDEX, &ifr);
+ if(rc < 0)
+ goto error;
+
+ reuse = 1;
+ rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
+ if(rc < 0)
+ goto error;
+
+ rc = bind(fd, spn, sizeof(struct sockaddr_pn));
+ if(rc < 0)
+ goto error;
+
+ common_data->fd = fd;
+
+ if(type == IPC_CLIENT_TYPE_RFS)
+ {
+ socket_rfs_magic = SOCKET_RFS_MAGIC;
+ rc = setsockopt(fd, SOL_SOCKET, SO_RFSMAGIC, &socket_rfs_magic, sizeof(socket_rfs_magic));
+ if(rc < 0)
+ goto error;
+ }
+
+ rc = phonet_iface_ifup();
+ if(rc < 0)
+ goto error;
+
+ goto end;
+
+error:
+ return -1;
+
+end:
+ return 0;
+}
+
+int aries_ipc_close(void *data, unsigned int size, void *io_data)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+ int fd = -1;
+
+ if(io_data == NULL)
+ return -1;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+ fd = common_data->fd;
+
+ if(fd < 0)
+ return -1;
+
+ close(fd);
+
+ return 0;
+}
+
+int aries_ipc_read(void *data, unsigned int size, void *io_data)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+ int spn_len;
+ int fd = -1;
+ int rc;
+
+ if(io_data == NULL)
+ return -1;
+
+ if(data == NULL)
+ return -1;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+ fd = common_data->fd;
+
+ if(fd < 0)
+ return -1;
+
+ spn_len = sizeof(struct sockaddr_pn);
+ rc = recvfrom(fd, data, size, 0, common_data->spn, &spn_len);
+
+ if(rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int aries_ipc_write(void *data, unsigned int size, void *io_data)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+ int spn_len;
+ int fd = -1;
+ int rc;
+
+ if(io_data == NULL)
+ return -1;
+
+ if(data == NULL)
+ return -1;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+ fd = common_data->fd;
+
+ if(fd < 0)
+ return -1;
+
+ spn_len = sizeof(struct sockaddr_pn);
+
+ rc = sendto(fd, data, size, 0, common_data->spn, spn_len);
+
+ if(rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int aries_ipc_power_on(void *data)
+{
+ int fd = open("/sys/class/modemctl/xmm/status", O_RDONLY);
+ char status[1] = { 0 };
+ char power_data[4] = "on";
+ int rc;
+
+ if(fd < 0)
+ return -1;
+
+ rc = read(fd, status, 1);
+
+ close(fd);
+
+ if(rc < 0)
+ return -1;
+
+ // it's already on
+ if(status[0] == '1')
+ return 0;
+
+ fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
+ if(fd < 0)
+ return -1;
+
+ rc = write(fd, power_data, 2);
+
+ close(fd);
+
+ if(rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int aries_ipc_power_off(void *data)
+{
+ int fd = open("/sys/class/modemctl/xmm/status", O_RDONLY);
+ char status[1] = { 0 };
+ char power_data[5] = "off";
+ int rc;
+
+ if(fd < 0)
+ return -1;
+
+ rc = read(fd, status, 1);
+
+ close(fd);
+
+ if(rc < 0)
+ return -1;
+
+ // it's already off
+ if(status[0] == '0')
+ return 0;
+
+ fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
+ if(fd < 0)
+ return -1;
+
+ rc = write(fd, power_data, 3);
+
+ close(fd);
+
+ if(rc < 0)
+ return -1;
+
+ return 0;
+}
+
+void *aries_ipc_common_data_create(void)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+ void *io_data;
+ int io_data_len;
+ int spn_len;
+
+ io_data_len = sizeof(struct aries_ipc_handlers_common_data);
+ io_data = malloc(io_data_len);
+
+ if(io_data == NULL)
+ return NULL;
+
+ memset(io_data, 0, io_data_len);
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+
+ spn_len = sizeof(struct sockaddr_pn);
+ common_data->spn = malloc(spn_len);
+
+ if(common_data == NULL)
+ return NULL;
+
+ memset(common_data->spn, 0, spn_len);
+
+ return io_data;
+}
+
+int aries_ipc_common_data_destroy(void *io_data)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+
+ // This was already done, not an error but we need to return
+ if(io_data == NULL)
+ return 0;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+
+ if(common_data->spn != NULL)
+ free(common_data->spn);
+
+ free(io_data);
+
+ return 0;
+}
+
+int aries_ipc_common_data_set_fd(void *io_data, int fd)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+
+ if(io_data == NULL)
+ return -1;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+ common_data->fd = fd;
+
+ return 0;
+}
+
+int aries_ipc_common_data_get_fd(void *io_data)
+{
+ struct aries_ipc_handlers_common_data *common_data;
+
+ if(io_data == NULL)
+ return -1;
+
+ common_data = (struct aries_ipc_handlers_common_data *) io_data;
+
+ return common_data->fd;
+}
+
+struct ipc_handlers ipc_default_handlers = {
+ .read = aries_ipc_read,
+ .write = aries_ipc_write,
+ .open = aries_ipc_open,
+ .close = aries_ipc_close,
+ .power_on = aries_ipc_power_on,
+ .power_off = aries_ipc_power_off,
+ .common_data = NULL,
+ .common_data_create = aries_ipc_common_data_create,
+ .common_data_destroy = aries_ipc_common_data_destroy,
+ .common_data_set_fd = aries_ipc_common_data_set_fd,
+ .common_data_get_fd = aries_ipc_common_data_get_fd,
+};
+
+struct ipc_ops ipc_fmt_ops = {
+ .send = aries_ipc_fmt_client_send,
+ .recv = aries_ipc_fmt_client_recv,
+ .bootstrap = aries_modem_bootstrap,
+};
+
+struct ipc_ops ipc_rfs_ops = {
+ .send = aries_ipc_rfs_client_send,
+ .recv = aries_ipc_rfs_client_recv,
+ .bootstrap = NULL,
+};
+
+// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.h b/samsung-ipc/device/aries/aries_ipc.h
index 05e0a5c..82c7286 100644
--- a/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.h
+++ b/samsung-ipc/device/aries/aries_ipc.h
@@ -2,6 +2,7 @@
* This file is part of libsamsung-ipc.
*
* Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
+ * Igor Almeida <igor.contato@gmail.com>
*
* libsamsung-ipc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,38 +19,37 @@
*
*/
-#ifndef __GALAXYSMTD_IPC_H__
-#define __GALAXYSMTD_IPC_H__
+#ifndef __ARIES_IPC_H__
+#define __ARIES_IPC_H__
+
+#include "phonet.h"
-//from trace/logcat: nCoreVer = 0xf0
#define BOOTCORE_VERSION 0xf0
-//from trace: write(14, "0", 1) before PSI_DATA_LEN
#define PSI_MAGIC 0x30
-//from trace/logcat: Bootloader IMG Size: 0x00005000, sent after PSI_MAGIC, LSB first
#define PSI_DATA_LEN 0x5000
-//from /radio/modem.bin size (0xc00000) - /efs/nv_data.bin size (0x2...)
-#define RADIO_IMG_SIZE 0xc00000-0x200000
+#define RADIO_IMG_MAX_SIZE 0xd80000
+#define RADIO_IMG_READ_SIZE 0xa00000
+#define ONENAND_MAP_SIZE 0xFFF000
+#define ONEDRAM_INIT_READ 0x12341234
+#define ONEDRAM_DEINIT_CMD 0x45674567
+#define ONEDRAM_DEINIT_READ 0xabcdabcd
+#define SO_RFSMAGIC 0x21
+#define SOCKET_RFS_MAGIC 0x80000
+#define PHONET_IFACE "svnet0"
+#define PHONET_SPN_RES_FMT 0x01
+#define PHONET_SPN_RES_RFS 0x41
-//should be the same from crespo
#define MAX_MODEM_DATA_SIZE 0x1000
-struct samsung_rfs_msg
-{
- uint32_t offset;
- uint32_t size;
-};
+int phonet_iface_ifdown(void);
+int phonet_iface_ifup(void);
-struct samsung_rfs_cfrm
+struct aries_ipc_handlers_common_data
{
- uint8_t confirmation;
- struct samsung_rfs_msg msg;
+ int fd;
+ struct sockaddr_pn *spn;
};
-int wake_lock(char *lock_name, int len);
-int wake_unlock(char *lock_name, int len);
-
-extern struct ipc_handlers galaxysmtd_ipc_default_handlers;
-
#endif
// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/aries/onedram.h b/samsung-ipc/device/aries/onedram.h
new file mode 100644
index 0000000..9c69c76
--- /dev/null
+++ b/samsung-ipc/device/aries/onedram.h
@@ -0,0 +1,30 @@
+/**
+ * header for onedram driver
+ *
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __ONEDRAM_H__
+#define __ONEDRAM_H__
+
+#include <linux/ioctl.h>
+
+#define ONEDRAM_GET_AUTH _IOW('o', 0x20, u32)
+#define ONEDRAM_PUT_AUTH _IO('o', 0x21)
+#define ONEDRAM_REL_SEM _IO('o', 0x22)
+
+#endif /* __ONEDRAM_H__ */
diff --git a/samsung-ipc/device/aries/phonet.h b/samsung-ipc/device/aries/phonet.h
new file mode 100644
index 0000000..edf36ec
--- /dev/null
+++ b/samsung-ipc/device/aries/phonet.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef NETPHONET_PHONET_H
+#define NETPHONET_PHONET_H
+
+#include <sys/types.h>
+
+#include <sys/socket.h>
+#ifndef AF_PHONET
+#define AF_PHONET 35
+#define PF_PHONET AF_PHONET
+#endif
+
+#define PN_PROTO_TRANSPORT 0
+#define PN_PROTO_PHONET 1
+#define PN_PROTO_PIPE 2
+
+#define SOL_PNPIPE 275
+
+#define PNPIPE_ENCAP 1
+#define PNPIPE_IFINDEX 2
+
+#define PNPIPE_ENCAP_NONE 0
+#define PNPIPE_ENCAP_IP 1
+
+#define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0)
+#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14)
+#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15)
+
+struct sockaddr_pn {
+ sa_family_t spn_family;
+ uint8_t spn_obj;
+ uint8_t spn_dev;
+ uint8_t spn_resource;
+ uint8_t __pad[sizeof(struct sockaddr) - (sizeof(sa_family_t) + 3)];
+} __attribute__ ((packed));
+
+#include <linux/rtnetlink.h>
+#ifndef RTNLGRP_PHONET_IFADDR
+#define RTNLGRP_PHONET_IFADDR 21
+#endif
+
+#endif
diff --git a/samsung-ipc/device/aries/sipc4.h b/samsung-ipc/device/aries/sipc4.h
new file mode 100644
index 0000000..616d005
--- /dev/null
+++ b/samsung-ipc/device/aries/sipc4.h
@@ -0,0 +1,256 @@
+/**
+ * SAMSUNG MODEM IPC header version 4
+ *
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __SAMSUNG_IPC_V4_H__
+#define __SAMSUNG_IPC_V4_H__
+
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+/* IPC4.1 NEW PARTITION MAP
+ * This map is seen by AP side
+
+ 0x00_0000 ===========================================
+ MAGIC(4)| ACCESS(4) | RESERVED(8)
+ 0x00_0010 -------------------------------------------
+ FMT_OUT_PTR | FMT_IN_PTR
+ HEAD(4) | TAIL(4) | HEAD(4) | TAIL(4)
+ 0x00_0020 -------------------------------------------
+ RAW_OUT_PTR | RAW_IN_PTR
+ HEAD(4) | TAIL(4) | HEAD(4) | TAIL(4)
+ 0x00_0030 -------------------------------------------
+ RFS_OUT_PTR | RFS_IN_PTR
+ HEAD(4) | TAIL(4) | HEAD(4) | TAIL(4)
+ 0x00_0040 -------------------------------------------
+ RESERVED (4KB - 64B)
+ 0x00_1000 -------------------------------------------
+ CP Fatal Display (160B)
+ 0x00_10A0 -------------------------------------------
+ RESERVED (1MB - 4kb-4kb-4kb - 160B)
+ 0x0F_E000 -------------------------------------------
+ Formatted Out (4KB)
+ 0x0F_F000 -------------------------------------------
+ Formatted In (4KB)
+ 0x10_0000 ===========================================
+ Raw Out (1MB)
+ 0x20_0000 ===========================================
+ Raw In (1MB)
+ 0x30_0000 ===========================================
+ RemoteFS Out (1MB)
+ 0x40_0000 ===========================================
+ RemoteFS In (1MB)
+ 0x50_0000 ===========================================
+
+ 0xFF_FFFF ===========================================
+*/
+
+#define FMT_OUT 0x0FE000
+#define FMT_IN 0x0FF000
+#define FMT_SZ 0x1000 /* 4096 bytes */
+
+#define RAW_OUT 0x100000
+#define RAW_IN 0x200000
+#define RAW_SZ 0x100000 /* 1 MB */
+
+#define RFS_OUT 0x300000
+#define RFS_IN 0x400000
+#define RFS_SZ 0x100000 /* 1 MB */
+
+#define FATAL_DISP 0x001000
+#define FATAL_DISP_SZ 0xA0 /* 160 bytes */
+
+#define SIPC_MAP_SIZE (RFS_IN + RFS_SZ)
+#define SIPC_NAME "IPCv4.1"
+
+enum {
+ IPCIDX_FMT = 0,
+ IPCIDX_RAW,
+ IPCIDX_RFS,
+ IPCIDX_MAX
+};
+
+struct ringbuf_cont {
+ u32 out_head;
+ u32 out_tail;
+ u32 in_head;
+ u32 in_tail;
+};
+
+struct sipc_mapped { /* map to the onedram start addr */
+ u32 magic;
+ u32 access;
+ u32 hwrev;
+ u32 reserved;
+
+ struct ringbuf_cont rbcont[IPCIDX_MAX];
+};
+
+
+#define PN_CMD 0x00
+#define PN_FMT 0x01
+#define PN_RFS 0x41
+#define PN_RAW(chid) (0x20 | (chid))
+#define CHID(x) ((x) & 0x1F)
+
+#define res_to_ridx(x) ((x) >> 5)
+
+/*
+ * IPC Frame Format
+ */
+#define HDLC_START 0x7F
+#define HDLC_END 0x7E
+
+/* Formatted IPC Frame */
+struct fmt_hdr {
+ u16 len;
+ u8 control;
+} __attribute__ ((packed));
+
+#define FMT_ID_MASK 0x7F /* Information ID mask */
+#define FMT_ID_SIZE 0x80 /* = 128 ( 0 ~ 127 ) */
+#define FMT_MB_MASK 0x80 /* More bit mask */
+
+#define FMT_TX_MIN 5 /* ??? */
+
+#define is_fmt_last(x) (!((x) & FMT_MB_MASK))
+
+/* RAW IPC Frame */
+struct raw_hdr {
+ u32 len;
+ u8 channel;
+ u8 control;
+} __attribute__ ((packed));
+
+
+/* RFS IPC Frame */
+struct rfs_hdr {
+ u32 len;
+ u8 cmd;
+ u8 id;
+} __attribute__ ((packed));
+
+/*
+ * RAW frame channel ID
+ */
+enum {
+ CHID_0 = 0,
+ CHID_CSD_VT_DATA,
+ CHID_PDS_PVT_CONTROL,
+ CHID_PDS_VT_AUDIO,
+ CHID_PDS_VT_VIDEO,
+ CHID_5, /* 5 */
+ CHID_6,
+ CHID_CDMA_DATA,
+ CHID_PCM_DATA,
+ CHID_TRANSFER_SCREEN,
+ CHID_PSD_DATA1, /* 10 */
+ CHID_PSD_DATA2,
+ CHID_PSD_DATA3,
+ CHID_PSD_DATA4,
+ CHID_PSD_DATA5,
+ CHID_PSD_DATA6, /* 15 */
+ CHID_PSD_DATA7,
+ CHID_PSD_DATA8,
+ CHID_PSD_DATA9,
+ CHID_PSD_DATA10,
+ CHID_PSD_DATA11, /* 20 */
+ CHID_PSD_DATA12,
+ CHID_PSD_DATA13,
+ CHID_PSD_DATA14,
+ CHID_PSD_DATA15,
+ CHID_BT_DUN, /* 25 */
+ CHID_CIQ_BRIDGE_DATA,
+ CHID_27,
+ CHID_CP_LOG1,
+ CHID_CP_LOG2,
+ CHID_30, /* 30 */
+ CHID_31,
+ CHID_MAX
+};
+
+#define PDP_MAX 15
+#define PN_PDP_START PN_RAW(CHID_PSD_DATA1)
+#define PN_PDP_END PN_RAW(CHID_PSD_DATA15)
+
+#define PN_PDP(chid) (0x20 | ((chid) + CHID_PSD_DATA1 - 1))
+#define PDP_ID(res) ((res) - PN_PDP_START)
+
+
+/*
+ * IPC 4.0 Mailbox message definition
+ */
+#define MB_VALID 0x0080
+#define MB_COMMAND 0x0040
+
+#define MB_CMD(x) (MB_VALID | MB_COMMAND | x)
+#define MB_DATA(x) (MB_VALID | x)
+
+/*
+ * If not command
+ */
+#define MBD_SEND_FMT 0x0002
+#define MBD_SEND_RAW 0x0001
+#define MBD_SEND_RFS 0x0100
+#define MBD_REQ_ACK_FMT 0x0020
+#define MBD_REQ_ACK_RAW 0x0010
+#define MBD_REQ_ACK_RFS 0x0400
+#define MBD_RES_ACK_FMT 0x0008
+#define MBD_RES_ACK_RAW 0x0004
+#define MBD_RES_ACK_RFS 0x0200
+
+/*
+ * If command
+ */
+enum {
+ MBC_NONE = 0,
+ MBC_INIT_START, // 0x0001
+ MBC_INIT_END, // 0x0002
+ MBC_REQ_ACTIVE, // 0x0003
+ MBC_RES_ACTIVE, // 0x0004
+ MBC_TIME_SYNC, // 0x0005
+ MBC_POWER_OFF, // 0x0006
+ MBC_RESET, // 0x0007
+ MBC_PHONE_START, // 0x0008
+ MBC_ERR_DISPLAY, // 0x0009
+ MBC_POWER_SAVE, // 0x000A
+ MBC_NV_REBUILD, // 0x000B
+ MBC_EMER_DOWN, // 0x000C
+ MBC_REQ_SEM, // 0x000D
+ MBC_RES_SEM, // 0x000E
+ MBC_MAX // 0x000F
+};
+#define MBC_MASK 0xFF
+
+/* CMD_INIT_END extended bit */
+#define CP_BOOT_ONLINE 0x0000
+#define CP_BOOT_AIRPLANE 0x1000
+#define AP_OS_ANDROID 0x0100
+#define AP_OS_WINMOBILE 0x0200
+#define AP_OS_LINUX 0x0300
+#define AP_OS_SYMBIAN 0x0400
+
+/* CMD_PHONE_START extended bit */
+#define CP_QUALCOMM 0x0100
+#define CP_INFINEON 0x0200
+#define CP_BROADCOM 0x0300
+
+#endif /* __SAMSUNG_IPC_V4_H__ */
+
diff --git a/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c b/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c
deleted file mode 100644
index 7ddfb91..0000000
--- a/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c
+++ /dev/null
@@ -1,644 +0,0 @@
-/**
- * This file is part of libsamsung-ipc.
- *
- * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
- * Joerie de Gram <j.de.gram@gmail.com>
- * Simon Busch <morphis@gravedo.de>
- *
- * libsamsung-ipc 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.
- *
- * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <mtd/mtd-abi.h>
-#include <assert.h>
-
-#include <radio.h>
-
-#include "galaxysmtd_modem_ctl.h"
-#include "galaxysmtd_nv_data.h"
-#include "galaxysmtd_ipc.h"
-#include "ipc_private.h"
-
-int wake_lock_fd= -1;
-int wake_unlock_fd= -1;
-
-int galaxysmtd_modem_bootstrap(struct ipc_client *client)
-{
- int s3c2410_serial3_fd= -1;
- int modem_ctl_fd= -1;
-
- /* Control variables. */
- int boot_tries_count=0;
- int rc=0;
-
- /* Boot variables */
- uint8_t *radio_img_p=NULL;
- uint8_t bootcore_version=0;
- uint8_t info_size=0;
- uint8_t crc_byte=0;
- int block_size=0;
-
- /* s3c2410 serial setup variables. */
- struct termios termios;
- int serial;
-
- /* fds maniplation variables */
- struct timeval timeout;
- fd_set fds;
-
- /* nv_data variables */
- void *nv_data_p;
-
- /* General purpose variables. */
- uint8_t data;
- uint16_t data_16;
- uint8_t *data_p;
- unsigned int modem_ctl_data;
- int i;
- void *onedram_map=NULL;
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: enter");
-
-boot_loop_start:
- if(boot_tries_count > 5)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: boot has failed too many times.");
- goto error;
- }
-
- //TODO try to disable svnet0 first?
-
- /* Read the radio.img image. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: reading radio image");
- radio_img_p = ipc_mtd_read(client, "/dev/block/bml12", RADIO_IMG_SIZE, 0x1000);
- if (radio_img_p == NULL) {
- goto error;
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: radio image read");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: open modem_ctl");
- modem_ctl_fd = open("/dev/onedram", O_RDWR);
- if(modem_ctl_fd < 0)
- goto error_loop;
-
- /* Reset the modem before init to send the first part of modem.bin. */
- ipc_client_power_off(client);
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PHONE \"off\" command");
- usleep(1000);
- ipc_client_power_on(client);
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PHONE \"on\" command");
- usleep(200000);
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: open s3c2410_serial3");
- s3c2410_serial3_fd = open("/dev/s3c2410_serial3", O_RDWR);
- if(s3c2410_serial3_fd < 0)
- goto error_loop;
-
- /* Setup the s3c2410 serial. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: setup s3c2410_serial3");
-
- ioctl(s3c2410_serial3_fd, TIOCMGET, &serial); //FIXME
- ioctl(s3c2410_serial3_fd, TIOCMSET, &serial); //FIXME
-
- tcgetattr(s3c2410_serial3_fd, &termios); //FIXME
- tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios); //FIXME
-
- tcgetattr(s3c2410_serial3_fd, &termios);
-
- cfmakeraw(&termios);
- cfsetispeed(&termios, B115200);
- cfsetospeed(&termios, B115200);
-
- tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios);
-
- /* Send 'AT' in ASCII. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sending AT in ASCII");
- for(i=0 ; i < 20 ; i++)
- {
- rc = write(s3c2410_serial3_fd, "AT", 2);
- usleep(50000);
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sending AT in ASCII done");
-
- usleep(50000); //FIXME
-
- /* Get and check bootcore version. */
- read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version));
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got bootcore version: 0x%x", bootcore_version);
-
- if(bootcore_version != BOOTCORE_VERSION)
- goto error_loop;
-
- /* Get info_size. */
- read(s3c2410_serial3_fd, &info_size, sizeof(info_size));
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got info_size: 0x%x", info_size);
-
- /* Send PSI magic. */
- data=PSI_MAGIC;
- write(s3c2410_serial3_fd, &data, sizeof(data));
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PSI_MAGIC (0x%x)", PSI_MAGIC);
-
- /* Send PSI data len. */
- data_16=PSI_DATA_LEN;
- data_p=(uint8_t *)&data_16;
-
- for(i=0 ; i < 2 ; i++)
- {
- write(s3c2410_serial3_fd, data_p, 1);
- data_p++;
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)", PSI_DATA_LEN);
-
- /* Write the first part of modem.img. */
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
-
- timeout.tv_sec=5;
- timeout.tv_usec=0;
-
- data_p=radio_img_p;
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sending the first part of modem.bin");
-
- crc_byte=0;
- for(i=0 ; i < PSI_DATA_LEN ; i++)
- {
- if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- write(s3c2410_serial3_fd, data_p, 1);
- crc_byte=crc_byte ^ *data_p;
-
- data_p++;
- }
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: first part of modem.bin sent; crc_byte is 0x%x", crc_byte);
-
- if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: crc_byte sent");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wait for ACK");
- data = 0;
- for(i = 0 ; data != 0x01 ; i++)
- {
- if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- read(s3c2410_serial3_fd, &data, sizeof(data));
-
- if(i > 50)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: fairly too much attempts to get ACK");
- goto error_loop;
- }
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got ACK");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: close s3c2410_serial3");
- close(s3c2410_serial3_fd);
-
- FD_ZERO(&fds);
- FD_SET(modem_ctl_fd, &fds);
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wait for 0x12341234");
- if(select(modem_ctl_fd+1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- read(modem_ctl_fd, &modem_ctl_data, sizeof(modem_ctl_data));
- if(modem_ctl_data != 0x12341234) {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wrong ACK flag from modem_ctl");
- goto error_loop;
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got 0x12341234");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: writing the rest of modem.bin to modem_ctl.");
-
- /* Pointer to the remaining part of radio.img. */
- data_p=radio_img_p + PSI_DATA_LEN;
-
- size_t map_length = 16773120; //magic buflen comes from proprietary ril trace
- onedram_map = mmap(NULL, map_length, PROT_READ|PROT_WRITE, MAP_SHARED, modem_ctl_fd, 0);
- if(onedram_map == -1) {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: could not map onedram to memory");
- goto error_loop;
- }
-
- memcpy(onedram_map, data_p, RADIO_IMG_SIZE - PSI_DATA_LEN);
-
- free(radio_img_p);
-
- /* nv_data part. */
-
- /* Check if all the nv_data files are ok. */
- nv_data_check(client);
-
- /* Check if the MD5 is ok. */
- nv_data_md5_check(client);
-
- /* Write nv_data.bin to modem_ctl. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: write nv_data to modem_ctl");
-
- nv_data_p = ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, 1024);
- if (nv_data_p == NULL)
- goto error;
- data_p = nv_data_p;
-
- //seems 0xd80000 is the absolute maximum for the radio_img, like crespo
- //uses. it creates a gap though, since we only write 0x9fb000 bytes to /dev/onedram
- memcpy(onedram_map + 0xd80000, data_p, NV_DATA_SIZE);
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: done writing nv_data");
-
- free(nv_data_p);
- munmap(onedram_map, map_length);
-
- //TODO finalize bootstrap
- ioctl(modem_ctl_fd, 0x6f22, 0); //magic request comes from proprietary ril trace
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: send 0x45674567");
- modem_ctl_data = 0x45674567;
- write(modem_ctl_fd, &modem_ctl_data, sizeof(modem_ctl_data));
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wait for 0xabcdabcd");
- for(i = 0 ; modem_ctl_data != 0xabcdabcd ; i++)
- {
- if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- read(modem_ctl_fd, &modem_ctl_data, sizeof(modem_ctl_data));
-
- if(i > 10)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: fairly too much attempts to get 0xabcdabcd");
- goto error_loop;
- }
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got 0xabcdabcd");
-
- close(modem_ctl_fd);
-
- rc = 0;
- goto exit;
-
-error_loop:
- ipc_client_log(client, "%s: something went wrong", __func__);
- boot_tries_count++;
- sleep(2);
-
- goto boot_loop_start;
-
-error:
- ipc_client_log(client, "%s: something went wrong", __func__);
- rc = 1;
-exit:
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: exit");
- return rc;
-}
-
-int crespo_ipc_client_send(struct ipc_client *client, struct ipc_message_info *request)
-{
- struct modem_io modem_data;
- struct ipc_header reqhdr;
- int rc = 0;
-
- memset(&modem_data, 0, sizeof(struct modem_io));
- modem_data.size = request->length + sizeof(struct ipc_header);
-
- reqhdr.mseq = request->mseq;
- reqhdr.aseq = request->aseq;
- reqhdr.group = request->group;
- reqhdr.index = request->index;
- reqhdr.type = request->type;
- reqhdr.length = (uint16_t) (request->length + sizeof(struct ipc_header));
-
- modem_data.data = malloc(reqhdr.length);
-
- memcpy(modem_data.data, &reqhdr, sizeof(struct ipc_header));
- memcpy((unsigned char *) (modem_data.data + sizeof(struct ipc_header)), request->data, request->length);
-
- assert(client->handlers->write != NULL);
-
- ipc_client_log(client, "INFO: crespo_ipc_client_send: Modem SEND FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
- ipc_client_log(client, "INFO: crespo_ipc_client_send: request: type = %d (%s), group = %d, index = %d (%s)",
- request->type, ipc_request_type_to_str(request->type), request->group, request->index, ipc_command_type_to_str(IPC_COMMAND(request)));
-
-#ifdef DEBUG
- if(request->length > 0)
- {
- ipc_client_log(client, "INFO: ==== DATA DUMP ====");
- ipc_hex_dump(client, (void *) request->data, request->length);
- }
-#endif
-
- ipc_client_log(client, "");
-
- rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->write_data);
- return rc;
-}
-
-int wake_lock(char *lock_name, int len)
-{
- int rc = 0;
-
- wake_lock_fd = open("/sys/power/wake_lock", O_RDWR);
- rc = write(wake_lock_fd, lock_name, len);
- close(wake_lock_fd);
-
- return rc;
-}
-
-int wake_unlock(char *lock_name, int len)
-{
- int rc = 0;
-
- wake_lock_fd = open("/sys/power/wake_unlock", O_RDWR);
- rc = write(wake_lock_fd, lock_name, len);
- close(wake_unlock_fd);
-
- return rc;
-}
-
-int galaxysmtd_ipc_client_recv(struct ipc_client *client, struct ipc_message_info *response)
-{
- struct modem_io modem_data;
- struct ipc_header *resphdr;
- int bread = 0;
-
- memset(&modem_data, 0, sizeof(struct modem_io));
- modem_data.data = malloc(MAX_MODEM_DATA_SIZE);
- modem_data.size = MAX_MODEM_DATA_SIZE;
-
- memset(response, 0, sizeof(struct ipc_message_info));
-
- wake_lock("secril_fmt-interface", 20);
-
- assert(client->handlers->read != NULL);
- ipc_client_log(client, "INFO: galaxysmtd_ipc_client_recv -> read");
- bread = client->handlers->read((uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE, client->handlers->read_data);
- ipc_client_log(client, "INFO: galaxysmtd_ipc_client_recv read something");
- if (bread < 0)
- {
- ipc_client_log(client, "ERROR: galaxysmtd_ipc_client_recv: can't receive enough bytes from modem to process incoming response!");
- return 1;
- }
-
- ipc_client_log(client, "INFO: galaxysmtd_ipc_client_recv: Modem RECV FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
-
- if(modem_data.size <= 0 || modem_data.size >= 0x1000 || modem_data.data == NULL)
- {
- ipc_client_log(client, "ERROR: galaxysmtd_ipc_client_recv: we retrieve less bytes from the modem than we exepected!");
- return 1;
- }
-
- /* You MUST send back modem_data */
-
- resphdr = (struct ipc_header *) modem_data.data;
-
- response->mseq = resphdr->mseq;
- response->aseq = resphdr->aseq;
- response->group = resphdr->group;
- response->index = resphdr->index;
- response->type = resphdr->type;
- response->length = modem_data.size - sizeof(struct ipc_header);
- response->data = NULL;
-
- ipc_client_log(client, "INFO: crespo_ipc_client_recv: response: type = %d (%s), group = %d, index = %d (%s)",
- resphdr->type, ipc_response_type_to_str(resphdr->type), resphdr->group, resphdr->index, ipc_command_type_to_str(IPC_COMMAND(resphdr)));
-
- if(response->length > 0)
- {
-#ifdef DEBUG
- ipc_client_log(client, "INFO: ==== DATA DUMP ====");
- ipc_hex_dump(client, (void *) (modem_data.data + sizeof(struct ipc_header)), response->length);
-#endif
- response->data = malloc(response->length);
- memcpy(response->data, (uint8_t *) modem_data.data + sizeof(struct ipc_header), response->length);
- }
-
- free(modem_data.data);
-
- ipc_client_log(client, "");
-
- wake_unlock("secril_fmt-interface", 20);
-
- return 0;
-}
-
-int galaxysmtd_ipc_open(void *data, unsigned int size, void *io_data)
-{
- int type = *((int *) data);
- int fd = -1;
- int ret;
- char sadata[14];
-
- if(io_data == NULL)
- goto error;
-
- memset(sadata, 0, 14);
-
- const struct sockaddr saddr = {
- .sa_family = 0x23,
- .sa_data = sadata,
- };
-
- switch(type)
- {
- case IPC_CLIENT_TYPE_FMT:
- sadata[2] = 1;
- break;
- case IPC_CLIENT_TYPE_RFS:
- sadata[2] = 'A';
- break;
- default:
- break;
- }
-
- fd = socket(0x23, SOCK_DGRAM, 0);
-
- if(fd < 0)
- goto error;
-
- ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, "svnet0", 16);
- if(ret<0)
- goto error;
-
- ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, "\1\0\0\0", 4);
- if(ret<0)
- goto error;
-
- ret = bind(fd, &saddr, sizeof(struct sockaddr));
- if(ret<0)
- goto error;
-
- if(type == IPC_CLIENT_TYPE_RFS) {
- ret = setsockopt(fd, SOL_SOCKET, 0x21, "", 4);
- }
-
- *((int*)io_data) = fd;
- goto end;
-
-error:
- return -1;
-
-end:
- return 0;
-}
-
-int crespo_ipc_close(void *data, unsigned int size, void *io_data)
-{
- int fd = -1;
-
- if(io_data == NULL)
- return -1;
-
- fd = *((int *) io_data);
-
- if(fd < 0)
- return -1;
-
- close(fd);
-
- return 0;
-}
-
-int galaxysmtd_ipc_read(void *data, unsigned int size, void *io_data)
-{
- int fd = -1;
- int rc;
-
- if(io_data == NULL)
- return -1;
-
- if(data == NULL)
- return -1;
-
- fd = *((int *) io_data);
-
- if(fd < 0)
- return -1;
-
- rc = recvfrom(fd, data, size, 0, NULL, NULL);
-
- if(rc < 0)
- return -1;
-
- return 0;
-}
-
-int crespo_ipc_write(void *data, unsigned int size, void *io_data)
-{
- int fd = -1;
- int rc;
-
- if(io_data == NULL)
- return -1;
-
- fd = *((int *) io_data);
-
- if(fd < 0)
- return -1;
-
- rc = ioctl(fd, IOCTL_MODEM_SEND, data);
-
- if(rc < 0)
- return -1;
-
- return 0;
-}
-
-int galaxysmtd_ipc_power_on(void *data)
-{
- int fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
- int rc;
-
- if(fd < 0)
- return -1;
-
- rc = write(fd, "on", 2);
- close(fd);
-
- if(rc < 0)
- return -1;
-
- //TODO should check if nothing was written as well?
-
- return 0;
-}
-
-int galaxysmtd_ipc_power_off(void *data)
-{
- int fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
- int rc;
-
- if(fd < 0)
- return -1;
-
- rc = write(fd, "off", 3);
- close(fd);
-
- if(rc < 0)
- return -1;
-
- //TODO should check if nothing was written as well?
-
- return 0;
-}
-
-struct ipc_handlers ipc_default_handlers = {
- .read = galaxysmtd_ipc_read,
- .write = crespo_ipc_write,
- .open = galaxysmtd_ipc_open,
- .close = crespo_ipc_close,
- .power_on = galaxysmtd_ipc_power_on,
- .power_off = galaxysmtd_ipc_power_off,
-};
-
-struct ipc_ops ipc_ops = {
- .send = crespo_ipc_client_send,
- .recv = galaxysmtd_ipc_client_recv,
- .bootstrap = galaxysmtd_modem_bootstrap,
-};
-
-// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/galaxysmtd/galaxysmtd_modem_ctl.h b/samsung-ipc/device/galaxysmtd/galaxysmtd_modem_ctl.h
deleted file mode 100644
index 7c23165..0000000
--- a/samsung-ipc/device/galaxysmtd/galaxysmtd_modem_ctl.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2010 Samsung Electronics.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program 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.
- *
- */
-
-#ifndef __MODEM_CONTROL_H__
-#define __MODEM_CONTROL_H__
-
-#define IOCTL_MODEM_RAMDUMP _IO('o', 0x19)
-#define IOCTL_MODEM_RESET _IO('o', 0x20)
-#define IOCTL_MODEM_START _IO('o', 0x21)
-#define IOCTL_MODEM_OFF _IO('o', 0x22)
-
-#define IOCTL_MODEM_SEND _IO('o', 0x23)
-#define IOCTL_MODEM_RECV _IO('o', 0x24)
-
-struct modem_io {
- uint32_t size;
- uint32_t id;
- uint32_t cmd;
- void *data;
-};
-
-/* platform data */
-struct modemctl_data {
- const char *name;
- unsigned gpio_phone_active;
- unsigned gpio_pda_active;
- unsigned gpio_cp_reset;
- unsigned gpio_phone_on;
- bool is_cdma_modem; /* 1:CDMA Modem */
-};
-
-#endif
diff --git a/samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.c b/samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.c
deleted file mode 100644
index f4c3967..0000000
--- a/samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/**
- * This file is part of libsamsung-ipc.
- *
- * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
- *
- * libsamsung-ipc 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.
- *
- * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <openssl/md5.h>
-
-#include <radio.h>
-#include "galaxysmtd_nv_data.h"
-#include "galaxysmtd_ipc.h"
-
-void md5hash2string(char *out, uint8_t *in)
-{
- int i;
-
- for(i=0 ; i < MD5_DIGEST_LENGTH ; i++)
- {
- /* After the first iteration, we override \0. */
- if(*in < 0x10)
- sprintf(out, "0%x", *in);
- else
- sprintf(out, "%x", *in);
- in++;
- out+=2;
- }
-}
-
-void nv_data_generate(struct ipc_client *client)
-{
- ipc_client_log(client, "This feature isn't present yet\n");
-
-// nv_data_backup_create();
-}
-
-void nv_data_md5_compute(void *data_p, int size, void *hash)
-{
- MD5_CTX ctx;
-
-// MD5((unsigned char *)nv_data_p, nv_data_stat.st_size, nv_data_md5_hash);
-
- MD5_Init(&ctx);
- MD5_Update(&ctx, data_p, size);
- MD5_Update(&ctx, NV_DATA_MD5_SECRET, sizeof(NV_DATA_MD5_SECRET) - 1);
- MD5_Final(hash, &ctx);
-}
-
-void nv_data_backup_create(struct ipc_client *client)
-{
- uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
- char *nv_data_md5_hash_string;
-
- struct stat nv_stat;
- void *nv_data_p;
- uint8_t data;
- uint8_t *data_p;
-
- int fd;
- int i;
-
- ipc_client_log(client, "nv_data_backup_create: enter\n");
-
- if(stat("/efs/nv_data.bin", &nv_stat) < 0)
- {
- ipc_client_log(client, "nv_data_check: nv_data.bin missing\n");
- nv_data_generate(client);
- }
-
- /* Read the content of nv_data.bin. */
- nv_data_p=ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, NV_DATA_SIZE / 10);
-
- fd=open("/efs/.nv_data.bak", O_RDWR | O_CREAT, 0644);
-
- data_p=nv_data_p;
-
- /* Write the content of nv_data.bin in the backup file. */
- for(i=0 ; i < NV_DATA_SIZE / 10 ; i++)
- {
- write(fd, data_p, NV_DATA_SIZE / 10);
- data_p+=NV_DATA_SIZE / 10;
- }
-
- close(fd);
- free(nv_data_p);
-
- /* Alloc the memory for the md5 hash string. */
- nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
- memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
-
- /* Read the newly-written .nv_data.bak. */
- nv_data_p=ipc_file_read(client, "/efs/.nv_data.bak", NV_DATA_SIZE, NV_DATA_SIZE / 10);
-
- /* Compute the MD5 hash for .nv_data.bak.. */
- nv_data_md5_compute(nv_data_p, NV_DATA_SIZE, nv_data_md5_hash);
- md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
-
- ipc_client_log(client, "nv_data_backup_create: new MD5 hash is %s\n", nv_data_md5_hash_string);
-
- free(nv_data_p);
-
- /* Write the MD5 hash in nv_data.bin.md5. */
- fd=open("/efs/.nv_data.bak.md5", O_RDWR | O_CREAT, 0644);
-
- write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
-
- close(fd);
- free(nv_data_md5_hash_string);
-
- /* Write ASCII 1 on the state file. */
- fd=open("/efs/.nv_state", O_RDWR | O_CREAT, 0644);
-
- data='1';
- write(fd, &data, sizeof(data));
-
- close(fd);
-
- ipc_client_log(client, "nv_data_backup_create: exit\n");
-}
-
-void nv_data_backup_restore(struct ipc_client *client)
-{
- uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
- char *nv_data_md5_hash_string;
- char *nv_data_md5_hash_read;
-
- struct stat nv_stat;
- void *nv_data_p;
- uint8_t data;
- uint8_t *data_p;
-
- int fd;
- int i;
-
- ipc_client_log(client, "nv_data_backup_restore: enter\n");
-
- if(stat("/efs/.nv_data.bak", &nv_stat) < 0)
- {
- ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak missing\n");
- nv_data_generate(client);
- nv_data_backup_create(client);
- return;
- }
-
- if(nv_stat.st_size != NV_DATA_SIZE)
- {
- ipc_client_log(client, "nv_data_backup_restore: wrong .nv_data.bak size\n");
- nv_data_generate(client);
- nv_data_backup_create(client);
- return;
- }
-
- /* Read the content of the backup file. */
- nv_data_p=ipc_file_read(client, "/efs/.nv_data.bak", NV_DATA_SIZE, NV_DATA_SIZE / 10);
-
- fd=open("/efs/nv_data.bin", O_RDWR | O_CREAT, 0644);
-
- data_p=nv_data_p;
-
- /* Write the content of the backup file in nv_data.bin. */
- for(i=0 ; i < NV_DATA_SIZE / 10 ; i++)
- {
- write(fd, data_p, NV_DATA_SIZE / 10);
- data_p+=NV_DATA_SIZE / 10;
- }
-
- close(fd);
- free(nv_data_p);
-
- /* Alloc the memory for the md5 hashes strings. */
- nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
- nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);
-
- memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
- memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
-
- /* Read the newly-written nv_data.bin. */
- nv_data_p=ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, NV_DATA_SIZE / 10);
-
- /* Compute the MD5 hash for nv_data.bin. */
- nv_data_md5_compute(nv_data_p, NV_DATA_SIZE, nv_data_md5_hash);
- md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
-
- free(nv_data_p);
-
- /* Open the backup file MD5 hash. */
- fd=open("/efs/.nv_data.bak.md5", O_RDONLY);
-
- /* Read the md5 stored in the file. */
- read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
-
- /* Add 0x0 to end the string: not sure this is part of the file. */
- nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';
-
- ipc_client_log(client, "nv_data_backup_restore: computed MD5: %s read MD5: %s\n",
- nv_data_md5_hash_string, nv_data_md5_hash_read);
-
- /* Make sure both hashes are the same. */
- if(strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
- {
- ipc_client_log(client, "nv_data_md5_check: MD5 hash mismatch\n");
- nv_data_generate(client);
- nv_data_backup_create(client);
- return;
- }
-
- close(fd);
-
- /* Write the MD5 hash in nv_data.bin.md5. */
- fd=open("/efs/nv_data.bin.md5", O_RDWR | O_CREAT, 0644);
-
- write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
-
- close(fd);
-
- free(nv_data_md5_hash_string);
- free(nv_data_md5_hash_read);
-
- fd=open("/efs/.nv_state", O_RDWR | O_CREAT, 0644);
-
- data='1';
- write(fd, &data, sizeof(data));
-
- close(fd);
-
- ipc_client_log(client, "nv_data_backup_create: exit\n");
-}
-
-void nv_data_check(struct ipc_client *client)
-{
- struct stat nv_stat;
- int nv_state_fd=-1;
- int nv_state=0;
-
- ipc_client_log(client, "nv_data_check: enter\n");
-
- if(stat("/efs/nv_data.bin", &nv_stat) < 0)
- {
- ipc_client_log(client, "nv_data_check: nv_data.bin missing\n");
- nv_data_backup_restore(client);
- stat("/efs/nv_data.bin", &nv_stat);
- }
-
- if(nv_stat.st_size != NV_DATA_SIZE)
- {
- ipc_client_log(client, "nv_data_check: wrong nv_data.bin size\n");
- nv_data_backup_restore(client);
- }
-
- if(stat("/efs/.nv_data.bak", &nv_stat) < 0)
- {
- ipc_client_log(client, "nv_data_check: .nv_data.bak missing\n");
- nv_data_backup_create(client);
- }
-
- if(stat("/efs/nv_data.bin.md5", &nv_stat) < 0)
- {
- ipc_client_log(client, "nv_data_check: nv_data.bin.md5 missing\n");
- nv_data_backup_create(client);
- }
-
- nv_state_fd=open("/efs/.nv_state", O_RDONLY);
-
- if(nv_state_fd < 0 || fstat(nv_state_fd, &nv_stat) < 0)
- {
- ipc_client_log(client, "nv_data_check: .nv_state missing\n");
- nv_data_backup_restore(client);
- }
-
- read(nv_state_fd, &nv_state, sizeof(nv_state));
-
- close(nv_state_fd);
-
- if(nv_state != '1')
- {
- ipc_client_log(client, "nv_data_check: bad nv_state\n");
- nv_data_backup_restore(client);
- }
-
- ipc_client_log(client, "nv_data_check: everything should be alright\n");
- ipc_client_log(client, "nv_data_check: exit\n");
-}
-
-void nv_data_md5_check(struct ipc_client *client)
-{
- struct stat nv_stat;
- uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
- char *nv_data_md5_hash_string;
- char *nv_data_md5_hash_read;
- void *nv_data_p;
-
- int fd;
- uint8_t *data_p;
-
- ipc_client_log(client, "nv_data_md5_check: enter\n");
-
- nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
- nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);
-
- memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
- memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
-
- nv_data_p=ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, 1024);
- data_p=nv_data_p;
-
- nv_data_md5_compute(data_p, NV_DATA_SIZE, nv_data_md5_hash);
-
- md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
-
- free(nv_data_p);
-
- fd=open("/efs/nv_data.bin.md5", O_RDONLY);
-
- /* Read the md5 stored in the file. */
- read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
-
- /* Add 0x0 to end the string: not sure this is part of the file. */
- nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';
-
- ipc_client_log(client, "nv_data_md5_check: computed MD5: %s read MD5: %s\n",
- nv_data_md5_hash_string, nv_data_md5_hash_read);
-
- if(strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
- {
- ipc_client_log(client, "nv_data_md5_check: MD5 hash mismatch\n");
- nv_data_backup_restore(client);
- }
-
- free(nv_data_md5_hash_string);
- free(nv_data_md5_hash_read);
-
- ipc_client_log(client, "nv_data_md5_check: exit\n");
-}
-
-// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.h b/samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.h
deleted file mode 100644
index e82f3da..0000000
--- a/samsung-ipc/device/galaxysmtd/galaxysmtd_nv_data.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * This file is part of libsamsung-ipc.
- *
- * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
- *
- * libsamsung-ipc 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.
- *
- * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef __GALAXYSMTD_NV_DATA_H__
-#define __GALAXYSMTD_NV_DATA__
-
-#include <radio.h>
-
-#define NV_DATA_MD5_SECRET "Samsung_Android_RIL"
-#define NV_DATA_SIZE 0x200000
-
-#define MD5_STRING_SIZE MD5_DIGEST_LENGTH * 2 + 1
-
-void md5hash2string(char *out, uint8_t *in);
-void nv_data_generate(struct ipc_client *client);
-void nv_data_md5_compute(void *data_p, int size, void *hash);
-void nv_data_backup_create(struct ipc_client *client);
-void nv_data_backup_restore(struct ipc_client *client);
-void nv_data_check(struct ipc_client *client);
-void nv_data_md5_check(struct ipc_client *client);
-
-#endif
-
-// vim:ts=4:sw=4:expandtab