aboutsummaryrefslogtreecommitdiffstats
path: root/samsung-ipc
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2013-06-30 10:40:11 +0200
committerPaul Kocialkowski <contact@paulk.fr>2013-06-30 10:40:11 +0200
commitc79aeafe5a44717d04fe4d14edf0ed71e7052783 (patch)
tree568ce66450634065a0619dbc25f3c17c524260df /samsung-ipc
parent1edc56a5fcb62dfea78fc27e29d7d87eda8c5662 (diff)
downloadhardware_replicant_libsamsung-ipc-c79aeafe5a44717d04fe4d14edf0ed71e7052783.tar.gz
hardware_replicant_libsamsung-ipc-c79aeafe5a44717d04fe4d14edf0ed71e7052783.tar.bz2
hardware_replicant_libsamsung-ipc-c79aeafe5a44717d04fe4d14edf0ed71e7052783.zip
Split aries and crespo common code to xmm6160, along with major code rework
Change-Id: Id78c7ce62bf5b9b875b6bc3dd53e6bf21fa36c95 Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Diffstat (limited to 'samsung-ipc')
-rw-r--r--samsung-ipc/Makefile.am3
-rw-r--r--samsung-ipc/device/aries/aries_ipc.c774
-rw-r--r--samsung-ipc/device/aries/aries_ipc.h56
-rw-r--r--samsung-ipc/device/crespo/crespo_ipc.c552
-rw-r--r--samsung-ipc/device/crespo/crespo_ipc.h21
-rw-r--r--samsung-ipc/device/xmm6160/xmm6160.c304
-rw-r--r--samsung-ipc/device/xmm6160/xmm6160.h42
-rw-r--r--samsung-ipc/device/xmm6260/xmm6260_ipc.h2
-rw-r--r--samsung-ipc/ipc_devices.c4
-rw-r--r--samsung-ipc/ipc_devices.h4
10 files changed, 842 insertions, 920 deletions
diff --git a/samsung-ipc/Makefile.am b/samsung-ipc/Makefile.am
index 25d730f..154bb70 100644
--- a/samsung-ipc/Makefile.am
+++ b/samsung-ipc/Makefile.am
@@ -3,6 +3,7 @@ NULL =
AM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/samsung-ipc \
+ -I$(top_srcdir)/samsung-ipc/device/xmm6160 \
-I$(top_srcdir)/samsung-ipc/device/xmm6260 \
$(OPENSSL_CFLAGS) \
$(NULL)
@@ -39,6 +40,8 @@ libsamsung_ipc_la_SOURCES = \
device/aries/phonet.h \
device/crespo/crespo_modem_ctl.h \
device/crespo/crespo_ipc.h \
+ device/xmm6160/xmm6160.c \
+ device/xmm6160/xmm6160.h \
device/xmm6260/xmm6260_loader.c \
device/xmm6260/xmm6260_loader.h \
device/xmm6260/xmm6260_modemctl.c \
diff --git a/samsung-ipc/device/aries/aries_ipc.c b/samsung-ipc/device/aries/aries_ipc.c
index 2986321..4e3d273 100644
--- a/samsung-ipc/device/aries/aries_ipc.c
+++ b/samsung-ipc/device/aries/aries_ipc.c
@@ -22,544 +22,354 @@
*/
#include <stdlib.h>
+#include <stdio.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 <fcntl.h>
#include <sys/ioctl.h>
-#include <linux/netlink.h>
+#include <sys/mman.h>
#include <net/if.h>
-#include <asm/types.h>
-#include <mtd/mtd-abi.h>
-#include <assert.h>
-#include <string.h>
#include <samsung-ipc.h>
+#include <ipc.h>
+#include <util.h>
-#include "aries_ipc.h"
-#include "ipc.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;
-}
+#include "xmm6160.h"
+#include "aries_ipc.h"
int aries_ipc_bootstrap(struct ipc_client *client)
{
- int s3c2410_serial3_fd = -1;
- int onedram_fd = -1;
-
- /* Control variables. */
- int rc = 0;
+ void *modem_image_data = NULL;
+ void *onedram_address = NULL;
+ unsigned int onedram_init;
+ unsigned int onedram_magic;
+ unsigned int onedram_deinit;
- /* 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;
+ int onedram_fd = -1;
+ int serial_fd = -1;
- /* 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 rc;
int i;
- ipc_client_log(client, "aries_ipc_bootstrap: enter");
-
- /* Read the radio.img image. */
- ipc_client_log(client, "aries_ipc_bootstrap: reading radio image");
- radio_img_p = ipc_client_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, "Starting aries modem bootstrap");
- ipc_client_log(client, "aries_ipc_bootstrap: open onedram");
- onedram_fd=open("/dev/onedram", O_RDWR);
- if(onedram_fd < 0)
+ modem_image_data = file_data_read(MODEM_IMAGE_DEVICE, MODEM_IMAGE_SIZE, 0x1000);
+ if (modem_image_data == NULL) {
+ ipc_client_log(client, "Reading modem image data failed");
goto error;
-
- /* 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;
-
- /* 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");
-
- /* Write the first part of modem.img. */
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
+ ipc_client_log(client, "Read modem image data");
- timeout.tv_sec=5;
- timeout.tv_usec=0;
-
- if(select(s3c2410_serial3_fd + 1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ onedram_fd = open(ONEDRAM_DEVICE, O_RDWR);
+ if (onedram_fd < 0) {
+ ipc_client_log(client, "Opening onedram failed");
goto error;
}
+ ipc_client_log(client, "Opened onedram");
- /* 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)
+ rc = network_iface_down(MODEM_NETWORK_IFACE, AF_PHONET, SOCK_DGRAM);
+ if (rc < 0) {
+ ipc_client_log(client, "Turning modem network iface down failed");
goto error;
+ }
+ ipc_client_log(client, "Turned modem network iface down");
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
-
- timeout.tv_sec=5;
- timeout.tv_usec=0;
-
- if(select(s3c2410_serial3_fd + 1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ rc = ipc_client_power_off(client);
+ if (rc < 0) {
+ ipc_client_log(client, "Powering the modem off failed");
goto error;
}
+ ipc_client_log(client, "Powered the modem off");
- /* 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);
-
- /* Send PSI magic. */
- data=PSI_MAGIC;
- write(s3c2410_serial3_fd, &data, sizeof(uint8_t));
- 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;
+ usleep(1000);
- for(i=0 ; i < 2 ; i++)
- {
- write(s3c2410_serial3_fd, data_p, sizeof(uint8_t));
- data_p++;
+ rc = ipc_client_power_on(client);
+ if (rc < 0) {
+ ipc_client_log(client, "Powering the modem on failed");
+ goto error;
}
- ipc_client_log(client, "aries_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)", PSI_DATA_LEN);
-
- timeout.tv_sec=5;
- timeout.tv_usec=0;
+ ipc_client_log(client, "Powered the modem on");
- 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++)
- {
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
-
- if(select(s3c2410_serial3_fd + 1, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
- goto error;
- }
-
- write(s3c2410_serial3_fd, data_p, 1);
- crc_byte=crc_byte ^ *data_p;
-
- data_p++;
+ serial_fd = open(MODEM_SERIAL_DEVICE, O_RDWR | O_NDELAY);
+ if (serial_fd < 0) {
+ ipc_client_log(client, "Opening serial failed");
+ goto error;
}
+ ipc_client_log(client, "Opened serial");
- ipc_client_log(client, "aries_ipc_bootstrap: first part of radio.img sent; crc_byte is 0x%x", crc_byte);
+ usleep(100000);
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
-
- if(select(s3c2410_serial3_fd + 1, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ rc = xmm6160_psi_send(client, serial_fd, modem_image_data, MODEM_IMAGE_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM6160 PSI failed");
goto error;
}
+ ipc_client_log(client, "Sent XMM6160 PSI");
- write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));
-
- ipc_client_log(client, "aries_ipc_bootstrap: crc_byte sent");
+ onedram_init = 0;
- timeout.tv_sec=5;
- timeout.tv_usec=0;
+ FD_ZERO(&fds);
+ FD_SET(onedram_fd, &fds);
- data = 0;
- for(i = 0 ; data != 0x01 ; i++)
- {
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
+ timeout.tv_sec = 4;
+ timeout.tv_usec = 0;
- if(select(s3c2410_serial3_fd + 1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ i = 0;
+ do {
+ rc = select(onedram_fd + 1, &fds, NULL, NULL, &timeout);
+ if (rc <= 0) {
+ ipc_client_log(client, "Reading onedram init failed");
goto error;
}
- read(s3c2410_serial3_fd, &data, sizeof(data));
-
- if(i > 50)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: fairly too much attempts to get ACK");
+ rc = read(onedram_fd, &onedram_init, sizeof(onedram_init));
+ if (rc < (int) sizeof(onedram_init)) {
+ ipc_client_log(client, "Reading onedram init failed");
goto error;
}
- }
- ipc_client_log(client, "aries_ipc_bootstrap: close s3c2410_serial3");
- close(s3c2410_serial3_fd);
-
- timeout.tv_sec=3;
- timeout.tv_usec=0;
-
- ipc_client_log(client, "aries_ipc_bootstrap: wait for 0x%04x from onedram", ONEDRAM_INIT_READ);
-
- onedram_data = 0;
- while(onedram_data != ONEDRAM_INIT_READ) {
- FD_ZERO(&fds);
- FD_SET(onedram_fd, &fds);
-
- if(select(onedram_fd + 1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ if (i++ > 50) {
+ ipc_client_log(client, "Reading onedram init failed");
goto error;
}
+ } while (onedram_init != ONEDRAM_INIT);
+ ipc_client_log(client, "Read onedram init (0x%x)", onedram_init);
- read(onedram_fd, &onedram_data, sizeof(onedram_data));
-
- ipc_client_log(client, "aries_ipc_bootstrap: read 0x%04x from onedram", onedram_data);
+ onedram_address = mmap(NULL, ONEDRAM_MEMORY_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, onedram_fd, 0);
+ if (onedram_address == NULL || onedram_address == (void *) 0xffffffff) {
+ ipc_client_log(client, "Mapping onedram to memory failed");
+ goto error;
}
+ ipc_client_log(client, "Mapped onedram to memory");
- 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");
+ rc = xmm6160_modem_image_send(client, -1, onedram_address, modem_image_data, MODEM_IMAGE_SIZE, 0);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM6160 modem image failed");
goto error;
}
+ ipc_client_log(client, "Sent XMM6160 modem image");
- ipc_client_log(client, "aries_ipc_bootstrap: mapped onedram to 0x%x", onedram_p);
-
- 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. */
- if (nv_data_check(client) < 0)
- goto error;
-
- /* Check if the MD5 is ok. */
- if (nv_data_md5_check(client) < 0)
+ rc = xmm6160_nv_data_send(client, -1, onedram_address, NV_DATA_OFFSET);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM6160 nv_data failed");
goto error;
+ }
+ ipc_client_log(client, "Sent XMM6160 nv_data");
- /* Write nv_data.bin to modem_ctl. */
- ipc_client_log(client, "aries_ipc_bootstrap: write nv_data to onedram");
+ munmap(onedram_address, ONEDRAM_MEMORY_SIZE);
+ onedram_address = NULL;
- nv_data_p = ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client));
- if (nv_data_p == NULL)
+ rc = ioctl(onedram_fd, ONEDRAM_REL_SEM);
+ if (rc < 0)
goto error;
- data_p = nv_data_p;
-
- memcpy(onedram_p + RADIO_IMG_MAX_SIZE, data_p, nv_data_size(client));
-
- 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");
+ onedram_magic = ONEDRAM_MAGIC;
+ rc = write(onedram_fd, &onedram_magic, sizeof(onedram_magic));
+ if (rc < (int) sizeof(onedram_magic)) {
+ ipc_client_log(client, "Writing onedram magic failed");
goto error;
}
+ ipc_client_log(client, "Wrote onedram magic");
- onedram_data = ONEDRAM_DEINIT_CMD;
-
- ipc_client_log(client, "aries_ipc_bootstrap: send 0x%04x", onedram_data);
- write(onedram_fd, &onedram_data, sizeof(onedram_data));
-
- timeout.tv_sec=3;
- timeout.tv_usec=0;
-
- ipc_client_log(client, "aries_ipc_bootstrap: wait for 0x%04x from onedram", ONEDRAM_DEINIT_READ);
+ FD_ZERO(&fds);
+ FD_SET(onedram_fd, &fds);
- onedram_data = 0;
- while(onedram_data != ONEDRAM_DEINIT_READ) {
- FD_ZERO(&fds);
- FD_SET(onedram_fd, &fds);
+ timeout.tv_sec = 4;
+ timeout.tv_usec = 0;
- if(select(onedram_fd + 1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
+ i = 0;
+ do {
+ rc = select(onedram_fd + 1, &fds, NULL, NULL, &timeout);
+ if (rc <= 0) {
+ ipc_client_log(client, "Reading onedram deinit failed");
goto error;
}
- read(onedram_fd, &onedram_data, sizeof(onedram_data));
-
- ipc_client_log(client, "aries_ipc_bootstrap: read 0x%04x from onedram", onedram_data);
- }
+ rc = read(onedram_fd, &onedram_deinit, sizeof(onedram_deinit));
+ if (rc < (int) sizeof(onedram_deinit)) {
+ ipc_client_log(client, "Reading onedram deinit failed");
+ goto error;
+ }
- close(onedram_fd);
+ if (i++ > 50) {
+ ipc_client_log(client, "Reading onedram deinit failed");
+ goto error;
+ }
+ } while (onedram_deinit != ONEDRAM_DEINIT);
+ ipc_client_log(client, "Read onedram deinit (0x%x)", onedram_deinit);
rc = 0;
- goto exit;
+ goto complete;
error:
- ipc_client_log(client, "aries_ipc_bootstrap: something went wrong");
rc = -1;
-exit:
- ipc_client_log(client, "aries_ipc_bootstrap: exit");
+complete:
+ if (modem_image_data != NULL)
+ free(modem_image_data);
+
+ if (serial_fd >= 0)
+ close(serial_fd);
+
+ if (onedram_address != NULL)
+ munmap(onedram_address, ONEDRAM_MEMORY_SIZE);
+
+ if (onedram_fd >= 0)
+ close(onedram_fd);
+
return rc;
}
int aries_ipc_fmt_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));
+ struct ipc_header header;
+ void *buffer;
+ int rc;
- data = malloc(reqhdr.length);
+ if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || request == NULL)
+ return -1;
- memcpy(data, &reqhdr, sizeof(struct ipc_header));
- memcpy((unsigned char *) (data + sizeof(struct ipc_header)), request->data, request->length);
+ ipc_header_fill(&header, request);
- assert(client->handlers->write != NULL);
+ buffer = malloc(header.length);
+ memcpy(buffer, &header, sizeof(struct ipc_header));
+ if (request->data != NULL && request->length > 0)
+ memcpy((void *) ((unsigned char *) buffer + sizeof(struct ipc_header)), request->data, request->length);
ipc_client_log_send(client, request, __func__);
- rc = client->handlers->write(client->handlers->transport_data, data, reqhdr.length);
+ rc = client->handlers->write(client->handlers->transport_data, buffer, header.length);
+
+ free(buffer);
+
return rc;
}
int aries_ipc_fmt_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(client->handlers->transport_data, (uint8_t*) data, MAX_MODEM_DATA_SIZE);
+ struct ipc_header *header;
+ void *buffer = NULL;
+ int rc;
- if (bread < 0)
- {
- ipc_client_log(client, "aries_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!");
+ if (client == NULL || client->handlers == NULL || client->handlers->read == NULL || response == NULL)
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;
+ buffer = malloc(MODEM_DATA_SIZE);
+
+ rc = client->handlers->read(client->handlers->transport_data, buffer, MODEM_DATA_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Reading FMT data from the modem failed");
+ goto error;
}
- resphdr = (struct ipc_header *) data;
+ header = (struct ipc_header *) buffer;
- response->mseq = resphdr->mseq;
- response->aseq = resphdr->aseq;
- response->group = resphdr->group;
- response->index = resphdr->index;
- response->type = resphdr->type;
- response->cmd = IPC_COMMAND(response);
- response->length = resphdr->length - sizeof(struct ipc_header);
- response->data = NULL;
+ ipc_message_info_fill(header, response);
- if(response->length > 0)
- {
+ if (header->length > sizeof(struct ipc_header)) {
+ response->length = header->length - sizeof(struct ipc_header);
response->data = malloc(response->length);
- memcpy(response->data, (uint8_t *) data + sizeof(struct ipc_header), response->length);
+ memcpy(response->data, (void *) ((unsigned char *) buffer + sizeof(struct ipc_header)), response->length);
}
- free(data);
-
ipc_client_log_recv(client, response, __func__);
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (buffer != NULL)
+ free(buffer);
+
+ return rc;
+
return 0;
}
int aries_ipc_rfs_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));
+ struct rfs_hdr *header;
+ void *buffer;
+ int length;
+ int rc;
- rfs_hdr = (struct rfs_hdr *) data;
+ if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || request == NULL)
+ return -1;
- rfs_hdr->id = request->mseq;
- rfs_hdr->cmd = request->index;
- rfs_hdr->len = request->length + sizeof(struct rfs_hdr);
+ length = sizeof(struct rfs_hdr) + request->length;
+ buffer = malloc(length);
- memcpy((void *) (data + sizeof(struct rfs_hdr)), request->data, request->length);
+ header = (struct rfs_hdr *) buffer;
+ header->id = request->mseq;
+ header->cmd = request->index;
+ header->len = length;
- assert(client->handlers->write != NULL);
+ if (request->data != NULL && request->length > 0)
+ memcpy((void *) ((unsigned char *) buffer + sizeof(struct rfs_hdr)), request->data, request->length);
ipc_client_log_send(client, request, __func__);
- rc = client->handlers->write(client->handlers->transport_data, (uint8_t*) data, rfs_hdr->len);
+ rc = client->handlers->write(client->handlers->transport_data, buffer, length);
+
+ free(buffer);
+
return rc;
}
int aries_ipc_rfs_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));
+ struct rfs_hdr *header;
+ void *buffer = NULL;
+ int length;
+ int rc;
- assert(client->handlers->read != NULL);
- bread = client->handlers->read(client->handlers->transport_data, (uint8_t*) data, MAX_MODEM_DATA_SIZE);
- if (bread < 0)
- {
- ipc_client_log(client, "aries_ipc_rfs_client_recv: can't receive enough bytes from modem to process incoming response!");
+ if (client == NULL || client->handlers == NULL || client->handlers->read == NULL || response == NULL)
return -1;
- }
- rfs_hdr = (struct rfs_hdr *) data;
+ length = MODEM_DATA_SIZE;
+ buffer = malloc(length);
- 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;
+ rc = client->handlers->read(client->handlers->transport_data, buffer, length);
+ if (rc < 0) {
+ ipc_client_log(client, "Reading RFS data from the modem failed");
+ goto error;
}
- response->mseq = 0;
- response->aseq = rfs_hdr->id;
+ header = (struct rfs_hdr *) buffer;
+
+ memset(response, 0, sizeof(struct ipc_message_info));
+ response->aseq = header->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;
+ response->index = header->cmd;
- if(response->length > 0)
- {
+ if (header->len > sizeof(struct rfs_hdr)) {
+ response->length = header->len - sizeof(struct rfs_hdr);
response->data = malloc(response->length);
- memcpy(response->data, (uint8_t *) (data + sizeof(struct rfs_hdr)), response->length);
+ memcpy(response->data, (void *) ((unsigned char *) buffer + sizeof(struct rfs_hdr)), response->length);
}
- free(data);
-
ipc_client_log_recv(client, response, __func__);
- return 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (buffer != NULL)
+ free(buffer);
+
+ return rc;
}
int aries_ipc_open(void *transport_data, int type)
@@ -583,29 +393,29 @@ int aries_ipc_open(void *transport_data, int type)
spn = &data->spn;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, PHONET_IFACE, IFNAMSIZ);
+ strncpy(ifr.ifr_name, MODEM_NETWORK_IFACE, IFNAMSIZ);
spn->spn_family = AF_PHONET;
spn->spn_dev = 0;
- switch(type)
+ switch (type)
{
case IPC_CLIENT_TYPE_FMT:
- spn->spn_resource = PHONET_SPN_RES_FMT;
+ spn->spn_resource = MODEM_FMT_SPN_RESSOURCE;
break;
case IPC_CLIENT_TYPE_RFS:
- spn->spn_resource = PHONET_SPN_RES_RFS;
+ spn->spn_resource = MODEM_RFS_SPN_RESSOURCE;
break;
default:
break;
}
fd = socket(AF_PHONET, SOCK_DGRAM, 0);
- if(fd < 0)
+ if (fd < 0)
return -1;
rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifr.ifr_name, IFNAMSIZ);
- if(rc < 0)
+ if (rc < 0)
return -1;
rc = ioctl(fd, SIOCGIFINDEX, &ifr);
@@ -614,25 +424,25 @@ int aries_ipc_open(void *transport_data, int type)
reuse = 1;
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
- if(rc < 0)
+ if (rc < 0)
return -1;
- rc = bind(fd, spn, sizeof(struct sockaddr_pn));
- if(rc < 0)
+ rc = bind(fd, (const struct sockaddr *) spn, sizeof(struct sockaddr_pn));
+ if (rc < 0)
return -1;
data->fd = fd;
- if(type == IPC_CLIENT_TYPE_RFS)
+ 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)
+ socket_rfs_magic = MODEM_SOCKET_RFS_MAGIC;
+ rc = setsockopt(fd, SOL_SOCKET, SO_IPC_RFS, &socket_rfs_magic, sizeof(socket_rfs_magic));
+ if (rc < 0)
return -1;
}
- rc = phonet_iface_ifup();
- if(rc < 0)
+ rc = network_iface_up(MODEM_NETWORK_IFACE, AF_PHONET, SOCK_DGRAM);
+ if (rc < 0)
return -1;
return 0;
@@ -664,7 +474,7 @@ int aries_ipc_read(void *transport_data, void *buffer, unsigned int length)
int fd;
int rc;
- if (transport_data == NULL || buffer == NULL)
+ if (transport_data == NULL || buffer == NULL || length == 0)
return -1;
data = (struct aries_ipc_transport_data *) transport_data;
@@ -675,7 +485,7 @@ int aries_ipc_read(void *transport_data, void *buffer, unsigned int length)
spn_size = sizeof(struct sockaddr_pn);
- rc = recvfrom(fd, buffer, length, 0, &data->spn, &spn_size);
+ rc = recvfrom(fd, buffer, length, 0, (const struct sockaddr *) &data->spn, &spn_size);
if (rc < 0)
return -1;
@@ -689,7 +499,7 @@ int aries_ipc_write(void *transport_data, void *buffer, unsigned int length)
int fd;
int rc;
- if (transport_data == NULL || buffer == NULL)
+ if (transport_data == NULL || buffer == NULL || length == 0)
return -1;
data = (struct aries_ipc_transport_data *) transport_data;
@@ -700,7 +510,7 @@ int aries_ipc_write(void *transport_data, void *buffer, unsigned int length)
spn_size = sizeof(struct sockaddr_pn);
- rc = sendto(fd, buffer, length, 0, &data->spn, spn_size);
+ rc = sendto(fd, buffer, length, 0, (const struct sockaddr *) &data->spn, spn_size);
if (rc < 0)
return -1;
@@ -732,34 +542,20 @@ int aries_ipc_poll(void *transport_data, struct timeval *timeout)
int aries_ipc_power_on(void *power_data)
{
- int fd = open("/sys/class/modemctl/xmm/status", O_RDONLY);
- char status[1] = { 0 };
- char data[4] = "on";
+ char buffer[] = "on\n";
+ int value;
int rc;
- if(fd < 0)
- return -1;
-
- rc = read(fd, status, 1);
-
- close(fd);
-
- if(rc < 0)
+ value = sysfs_value_read(MODEMCTL_STATUS_SYSFS);
+ if (value < 0)
return -1;
- // it's already on
- if(status[0] == '1')
+ /* The modem is already on */
+ if (value == 1)
return 0;
- fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
- if(fd < 0)
- return -1;
-
- rc = write(fd, data, 2);
-
- close(fd);
-
- if(rc < 0)
+ rc = sysfs_string_write(MODEMCTL_CONTROL_SYSFS, (char *) &buffer, strlen(buffer));
+ if (rc < 0)
return -1;
return 0;
@@ -767,105 +563,64 @@ int aries_ipc_power_on(void *power_data)
int aries_ipc_power_off(void *power_data)
{
- int fd = open("/sys/class/modemctl/xmm/status", O_RDONLY);
- char status[1] = { 0 };
- char data[5] = "off";
+ char buffer[] = "off\n";
+ int value;
int rc;
- if(fd < 0)
+ value = sysfs_value_read(MODEMCTL_STATUS_SYSFS);
+ if (value < 0)
return -1;
- rc = read(fd, status, 1);
-
- close(fd);
-
- if(rc < 0)
- return -1;
-
- // it's already off
- if(status[0] == '0')
+ /* The modem is already off */
+ if (value == 0)
return 0;
- fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
- if(fd < 0)
- return -1;
-
- rc = write(fd, data, 3);
-
- close(fd);
-
- if(rc < 0)
+ rc = sysfs_string_write(MODEMCTL_CONTROL_SYSFS, (char *) &buffer, strlen(buffer));
+ if (rc < 0)
return -1;
return 0;
}
-int aries_ipc_gprs_activate(void *gprs_data, int cid)
+int aries_ipc_data_create(void **transport_data, void **power_data, void **gprs_data)
{
- int fd = open("/sys/class/net/svnet0/pdp/activate", O_RDWR);
- char *activate_data = NULL;
- int rc;
-
- if(fd < 0)
- return -1;
-
- asprintf(&activate_data, "%d\n", cid);
- if(activate_data == NULL)
+ if (transport_data == NULL)
return -1;
- rc = write(fd, activate_data, strlen(activate_data));
-
- free(activate_data);
- close(fd);
-
- if(rc < 0)
- return -1;
+ *transport_data = (void *) malloc(sizeof(struct aries_ipc_transport_data));
+ memset(*transport_data, 0, sizeof(struct aries_ipc_transport_data));
return 0;
-
}
-int aries_ipc_gprs_deactivate(void *gprs_data, int cid)
+int aries_ipc_data_destroy(void *transport_data, void *power_data, void *gprs_data)
{
- int fd = open("/sys/class/net/svnet0/pdp/deactivate", O_RDWR);
- char *deactivate_data = NULL;
- int rc;
-
- if(fd < 0)
- return -1;
-
- asprintf(&deactivate_data, "%d\n", cid);
- if(deactivate_data == NULL)
+ if (transport_data == NULL)
return -1;
- rc = write(fd, deactivate_data, strlen(deactivate_data));
-
- free(deactivate_data);
- close(fd);
-
- if(rc < 0)
- return -1;
+ free(transport_data);
return 0;
}
-int aries_ipc_data_create(void **transport_data, void **power_data, void **gprs_data)
+int aries_ipc_gprs_activate(void *gprs_data, int cid)
{
- if (transport_data == NULL)
- return -1;
+ int rc;
- *transport_data = (void *) malloc(sizeof(struct aries_ipc_transport_data));
- memset(*transport_data, 0, sizeof(struct aries_ipc_transport_data));
+ rc = sysfs_value_write(MODEM_PDP_ACTIVATE_SYSFS, cid);
+ if (rc < 0)
+ return -1;
return 0;
}
-int aries_ipc_data_destroy(void *transport_data, void *power_data, void *gprs_data)
+int aries_ipc_gprs_deactivate(void *gprs_data, int cid)
{
- if (transport_data == NULL)
- return -1;
+ int rc;
- free(transport_data);
+ rc = sysfs_value_write(MODEM_PDP_DEACTIVATE_SYSFS, cid);
+ if (rc < 0)
+ return -1;
return 0;
}
@@ -881,9 +636,10 @@ char *aries_ipc_gprs_get_iface(int cid)
memset(&ifr, 0, sizeof(ifr));
fd = socket(AF_PHONET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return NULL;
-
- for(i=GPRS_IFACE_COUNT-1 ; i >= 0 ; i--) {
+ for(i = (GPRS_IFACE_COUNT - 1); i >= 0; i--) {
sprintf(ifr.ifr_name, "%s%d", GPRS_IFACE_PREFIX, i);
rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
if(rc < 0 || ifr.ifr_flags & IFF_UP) {
diff --git a/samsung-ipc/device/aries/aries_ipc.h b/samsung-ipc/device/aries/aries_ipc.h
index 056fdfb..3e6aedc 100644
--- a/samsung-ipc/device/aries/aries_ipc.h
+++ b/samsung-ipc/device/aries/aries_ipc.h
@@ -1,8 +1,8 @@
-/**
+/*
* This file is part of libsamsung-ipc.
*
- * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
- * Igor Almeida <igor.contato@gmail.com>
+ * Copyright (C) 2011-2013 Paul Kocialkowski <contact@paulk.fr>
+ * Copyright (C) 2011 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
@@ -19,33 +19,35 @@
*
*/
+#include "phonet.h"
+
#ifndef __ARIES_IPC_H__
#define __ARIES_IPC_H__
-#include "phonet.h"
-
-#define BOOTCORE_VERSION 0xf0
-#define PSI_MAGIC 0x30
-#define PSI_DATA_LEN 0x5000
-#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
-
-#define MAX_MODEM_DATA_SIZE 0x1000
-
-#define GPRS_IFACE_PREFIX "pdp"
-#define GPRS_IFACE_COUNT 3
-
-int phonet_iface_ifdown(void);
-int phonet_iface_ifup(void);
+#define MODEM_IMAGE_SIZE 0xA00000
+#define NV_DATA_OFFSET 0xD80000
+#define ONEDRAM_MEMORY_SIZE 0xFFF000
+#define ONEDRAM_INIT 0x12341234
+#define ONEDRAM_MAGIC 0x45674567
+#define ONEDRAM_DEINIT 0xABCDABCD
+#define MODEM_DATA_SIZE 0x50000
+#define MODEM_SOCKET_RFS_MAGIC 0x80000
+
+#define SO_IPC_RFS 0x21
+#define MODEM_FMT_SPN_RESSOURCE 0x01
+#define MODEM_RFS_SPN_RESSOURCE 0x41
+
+#define MODEM_IMAGE_DEVICE "/dev/block/bml12"
+#define MODEM_SERIAL_DEVICE "/dev/s3c2410_serial3"
+#define ONEDRAM_DEVICE "/dev/onedram"
+#define MODEMCTL_STATUS_SYSFS "/sys/class/modemctl/xmm/status"
+#define MODEMCTL_CONTROL_SYSFS "/sys/class/modemctl/xmm/control"
+#define MODEM_NETWORK_IFACE "svnet0"
+#define MODEM_PDP_ACTIVATE_SYSFS "/sys/class/net/svnet0/pdp/activate"
+#define MODEM_PDP_DEACTIVATE_SYSFS "/sys/class/net/svnet0/pdp/deactivate"
+
+#define GPRS_IFACE_PREFIX "pdp"
+#define GPRS_IFACE_COUNT 3
struct aries_ipc_transport_data {
struct sockaddr_pn spn;
diff --git a/samsung-ipc/device/crespo/crespo_ipc.c b/samsung-ipc/device/crespo/crespo_ipc.c
index eae60d7..790b09c 100644
--- a/samsung-ipc/device/crespo/crespo_ipc.c
+++ b/samsung-ipc/device/crespo/crespo_ipc.c
@@ -1,9 +1,9 @@
-/**
+/*
* 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>
+ * Copyright (C) 2011-2013 Paul Kocialkowski <contact@paulk.fr>
+ * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
+ * Copyright (C) 2011 Joerie de Gram <j.de.gram@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
@@ -17,432 +17,247 @@
*
* 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 <stdio.h>
#include <stdint.h>
-#include <unistd.h>
#include <stdbool.h>
-#include <termios.h>
-#include <fcntl.h>
#include <string.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <mtd/mtd-abi.h>
-#include <assert.h>
#include <samsung-ipc.h>
+#include <ipc.h>
+#include <util.h>
#include "crespo_modem_ctl.h"
+
+#include "xmm6160.h"
#include "crespo_ipc.h"
-#include "ipc.h"
int crespo_ipc_bootstrap(struct ipc_client *client)
{
- int s3c2410_serial3_fd = -1;
- int modem_ctl_fd = -1;
+ void *modem_image_data = NULL;
- /* Control variables. */
- 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;
+ int modem_ctl_fd = -1;
+ int serial_fd = -1;
- /* nv_data variables */
- void *nv_data_p;
+ int rc;
- /* General purpose variables. */
- uint8_t data;
- uint16_t data_16;
- uint8_t *data_p;
- int i;
+ if (client == NULL)
+ return -1;
- ipc_client_log(client, "crespo_ipc_bootstrap: enter");
+ ipc_client_log(client, "Starting crespo modem bootstrap");
- /* Read the radio.img image. */
- ipc_client_log(client, "crespo_ipc_bootstrap: reading radio image");
- radio_img_p = ipc_client_mtd_read(client, "/dev/mtd/mtd5ro", RADIO_IMG_SIZE, 0x1000);
- if (radio_img_p == NULL) {
- radio_img_p = ipc_client_mtd_read(client, "/dev/mtd5ro", RADIO_IMG_SIZE, 0x1000);
- if (radio_img_p == NULL)
- goto error;
+ modem_image_data = file_data_read(MODEM_IMAGE_DEVICE, MODEM_IMAGE_SIZE, 0x1000);
+ if (modem_image_data == NULL) {
+ ipc_client_log(client, "Reading modem image data failed");
+ goto error;
}
- ipc_client_log(client, "crespo_ipc_bootstrap: radio image read");
+ ipc_client_log(client, "Read modem image data");
- ipc_client_log(client, "crespo_ipc_bootstrap: open modem_ctl");
- modem_ctl_fd=open("/dev/modem_ctl", O_RDWR | O_NDELAY);
- if(modem_ctl_fd < 0)
+ modem_ctl_fd = open(MODEM_CTL_DEVICE, O_RDWR | O_NDELAY);
+ if (modem_ctl_fd < 0) {
+ ipc_client_log(client, "Opening modem ctl failed");
goto error;
+ }
+ ipc_client_log(client, "Opened modem ctl");
- /* Reset the modem before init to send the first part of modem.img. */
rc = ioctl(modem_ctl_fd, IOCTL_MODEM_RESET);
- if (rc < 0)
+ if (rc < 0) {
+ ipc_client_log(client, "Resetting modem failed");
goto error;
-
- usleep(400000);
-
- ipc_client_log(client, "crespo_ipc_bootstrap: open s3c2410_serial3");
- s3c2410_serial3_fd=open("/dev/s3c2410_serial3", O_RDWR | O_NDELAY);
- if(s3c2410_serial3_fd < 0)
- goto error;
-
- /* Setup the s3c2410 serial. */
- ipc_client_log(client, "crespo_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, "crespo_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, "crespo_ipc_bootstrap: sending AT in ASCII done");
-
- usleep(50000); //FIXME
+ ipc_client_log(client, "Reset modem");
- /* Get and check bootcore version. */
- rc = read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version));
- if (rc < 0)
+ serial_fd = open(MODEM_SERIAL_DEVICE, O_RDWR | O_NDELAY);
+ if (serial_fd < 0) {
+ ipc_client_log(client, "Opening serial failed");
goto error;
-
- ipc_client_log(client, "crespo_ipc_bootstrap: got bootcore version: 0x%x", bootcore_version);
-
- if(bootcore_version != BOOTCORE_VERSION)
- goto error;
-
- /* Get info_size. */
- rc = read(s3c2410_serial3_fd, &info_size, sizeof(info_size));
- if (rc < 0)
- goto error;
-
- ipc_client_log(client, "crespo_ipc_bootstrap: got info_size: 0x%x", info_size);
-
- /* Send PSI magic. */
- data = PSI_MAGIC;
- rc = write(s3c2410_serial3_fd, &data, sizeof(data));
- if (rc < 0)
- goto error;
-
- ipc_client_log(client, "crespo_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++)
- {
- rc = write(s3c2410_serial3_fd, data_p, 1);
- if (rc < 0)
- goto error;
-
- data_p++;
}
- ipc_client_log(client, "crespo_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);
+ ipc_client_log(client, "Opened serial");
- timeout.tv_sec = 4;
- timeout.tv_usec = 0;
+ usleep(100000);
- data_p = radio_img_p;
-
- ipc_client_log(client, "crespo_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, "crespo_ipc_bootstrap: select timeout passed");
- goto error;
- }
-
- rc = write(s3c2410_serial3_fd, data_p, 1);
- if (rc < 0)
- goto error;
-
- crc_byte = crc_byte ^ *data_p;
- data_p++;
- }
-
- ipc_client_log(client, "crespo_ipc_bootstrap: first part of radio.img sent; crc_byte is 0x%x", crc_byte);
-
- if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
+ rc = xmm6160_psi_send(client, serial_fd, modem_image_data, MODEM_IMAGE_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM6160 PSI failed");
goto error;
}
+ ipc_client_log(client, "Sent XMM6160 PSI");
- rc = write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));
- if (rc < 0)
+ rc = xmm6160_modem_image_send(client, modem_ctl_fd, NULL, modem_image_data, MODEM_IMAGE_SIZE, 0);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM6160 modem image failed");
goto error;
-
- ipc_client_log(client, "crespo_ipc_bootstrap: crc_byte sent");
-
- data = 0;
- for (i = 0 ; data != 0x01 ; i++)
- {
- if (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
- goto error;
- }
-
- rc = read(s3c2410_serial3_fd, &data, sizeof(data));
- if (rc < 0)
- goto error;
-
- if(i > 50)
- {
- ipc_client_log(client, "crespo_ipc_bootstrap: fairly too much attempts to get ACK");
- goto error;
- }
- }
-
- ipc_client_log(client, "crespo_ipc_bootstrap: close s3c2410_serial3");
- close(s3c2410_serial3_fd);
-
- ipc_client_log(client, "crespo_ipc_bootstrap: writing the rest of radio.img to modem_ctl.");
- /* Seek to the begining of modem_ctl_fd (should already be so). */
- lseek(modem_ctl_fd, 0, SEEK_SET);
-
- /* Pointer to the remaining part of radio.img. */
- data_p = radio_img_p + PSI_DATA_LEN;
-
- FD_ZERO(&fds);
- FD_SET(modem_ctl_fd, &fds);
-
- block_size = 0x100000;
-
- for (i=0 ; i < (RADIO_IMG_SIZE - PSI_DATA_LEN) / block_size ; i++)
- {
- if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
- goto error;
- }
-
- rc = write(modem_ctl_fd, data_p, block_size);
- if (rc < 0)
- goto error;
-
- data_p += block_size;
}
+ ipc_client_log(client, "Sent XMM6160 modem image");
- free(radio_img_p);
-
- /* nv_data part. */
-
- /* Check if all the nv_data files are ok. */
- if (nv_data_check(client) < 0)
+ rc = xmm6160_nv_data_send(client, modem_ctl_fd, NULL, NV_DATA_OFFSET);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM6160 nv_data failed");
goto error;
-
- /* Check if the MD5 is ok. */
- if (nv_data_md5_check(client) < 0)
- goto error;
-
- /* Write nv_data.bin to modem_ctl. */
- ipc_client_log(client, "crespo_ipc_bootstrap: write nv_data to modem_ctl");
-
- nv_data_p = ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client));
- if (nv_data_p == NULL)
- goto error;
-
- data_p = nv_data_p;
- lseek(modem_ctl_fd, RADIO_IMG_SIZE, SEEK_SET);
-
- for(i=0 ; i < 2 ; i++)
- {
- rc = write(modem_ctl_fd, data_p, nv_data_size(client) / 2);
- if (rc < 0)
- goto error;
-
- data_p += nv_data_size(client) / 2;
}
-
- free(nv_data_p);
- close(modem_ctl_fd);
+ ipc_client_log(client, "Sent XMM6160 nv_data");
rc = 0;
- goto exit;
+ goto complete;
error:
- ipc_client_log(client, "%s: something went wrong", __func__);
rc = -1;
-exit:
- ipc_client_log(client, "crespo_ipc_bootstrap: exit");
+complete:
+ if (modem_image_data != NULL)
+ free(modem_image_data);
+
+ if (serial_fd >= 0)
+ close(serial_fd);
+
+ if (modem_ctl_fd >= 0)
+ close(modem_ctl_fd);
+
return rc;
}
int crespo_ipc_fmt_send(struct ipc_client *client, struct ipc_message_info *request)
{
- struct modem_io modem_data;
- struct ipc_header reqhdr;
- int rc = 0;
+ struct ipc_header header;
+ struct modem_io mio;
+ int rc;
- memset(&modem_data, 0, sizeof(struct modem_io));
- modem_data.size = request->length + sizeof(struct ipc_header);
+ if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || request == NULL)
+ return -1;
- 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));
+ ipc_header_fill(&header, request);
- modem_data.data = malloc(reqhdr.length);
+ memset(&mio, 0, sizeof(struct modem_io));
+ mio.size = request->length + sizeof(struct ipc_header);
+ mio.data = malloc(mio.size);
+ memcpy(mio.data, &header, sizeof(struct ipc_header));
+ if (request->data != NULL && request->length > 0)
+ memcpy((void *) ((unsigned char *) mio.data + sizeof(struct ipc_header)), request->data, request->length);
- memcpy(modem_data.data, &reqhdr, sizeof(struct ipc_header));
- memcpy((unsigned char *) (modem_data.data + sizeof(struct ipc_header)), request->data, request->length);
+ ipc_client_log_send(client, request, __func__);
- assert(client->handlers->write != NULL);
+ rc = client->handlers->write(client->handlers->transport_data, (void *) &mio, sizeof(struct modem_io));
- ipc_client_log_send(client, request, __func__);
+ free(mio.data);
- rc = client->handlers->write(client->handlers->transport_data, (uint8_t*) &modem_data, sizeof(struct modem_io));
return rc;
}
int crespo_ipc_fmt_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));
+ struct ipc_header *header;
+ struct modem_io mio;
+ int rc;
- assert(client->handlers->read != NULL);
- bread = client->handlers->read(client->handlers->transport_data, (uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE);
- if (bread < 0)
- {
- ipc_client_log(client, "crespo_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!");
+ if (client == NULL || client->handlers == NULL || client->handlers->read == NULL || response == NULL)
return -1;
- }
- if(modem_data.size <= 0 || modem_data.size >= MAX_MODEM_DATA_SIZE || modem_data.data == NULL)
- {
- ipc_client_log(client, "crespo_ipc_fmt_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
- return -1;
- }
+ memset(&mio, 0, sizeof(struct modem_io));
+ mio.size = MODEM_DATA_SIZE;
+ mio.data = malloc(mio.size);
- resphdr = (struct ipc_header *) modem_data.data;
+ rc = client->handlers->read(client->handlers->transport_data, &mio, sizeof(struct modem_io) + mio.size);
+ if (rc < 0 || mio.data == NULL || mio.size < sizeof(struct ipc_header)) {
+ ipc_client_log(client, "Reading FMT data from the modem failed");
+ goto error;
+ }
- response->mseq = resphdr->mseq;
- response->aseq = resphdr->aseq;
- response->group = resphdr->group;
- response->index = resphdr->index;
- response->type = resphdr->type;
- response->cmd = IPC_COMMAND(response);
- response->length = modem_data.size - sizeof(struct ipc_header);
- response->data = NULL;
+ header = (struct ipc_header *) mio.data;
+ ipc_message_info_fill(header, response);
- if(response->length > 0)
- {
+ if (mio.size > sizeof(struct ipc_header)) {
+ response->length = mio.size - sizeof(struct ipc_header);
response->data = malloc(response->length);
- memcpy(response->data, (uint8_t *) modem_data.data + sizeof(struct ipc_header), response->length);
+ memcpy(response->data, (void *) ((unsigned char *) mio.data + sizeof(struct ipc_header)), response->length);
}
- free(modem_data.data);
-
ipc_client_log_recv(client, response, __func__);
- return 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (mio.data != NULL)
+ free(mio.data);
+
+ return rc;
}
int crespo_ipc_rfs_send(struct ipc_client *client, struct ipc_message_info *request)
{
- struct modem_io modem_data;
- int rc = 0;
-
- memset(&modem_data, 0, sizeof(struct modem_io));
+ struct modem_io mio;
+ int rc;
- modem_data.id = request->mseq;
- modem_data.cmd = request->index;
+ if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || request == NULL)
+ return -1;
- modem_data.size = request->length;
- modem_data.data = malloc(request->length);
+ memset(&mio, 0, sizeof(struct modem_io));
+ mio.id = request->mseq;
+ mio.cmd = request->index;
+ mio.size = request->length;
+ if (request->data != NULL && request->length > 0) {
+ mio.data = malloc(mio.size);
+ memcpy(mio.data, request->data, request->length);
+ }
- memcpy(modem_data.data, request->data, request->length);
+ ipc_client_log_send(client, request, __func__);
- assert(client->handlers->write != NULL);
+ rc = client->handlers->write(client->handlers->transport_data, (void *) &mio, sizeof(struct modem_io));
- ipc_client_log_send(client, request, __func__);
+ if (mio.data != NULL)
+ free(mio.data);
- rc = client->handlers->write(client->handlers->transport_data, (uint8_t*) &modem_data, sizeof(struct modem_io));
return rc;
}
int crespo_ipc_rfs_recv(struct ipc_client *client, struct ipc_message_info *response)
{
- struct modem_io modem_data;
- 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));
+ struct modem_io mio;
+ int rc;
- assert(client->handlers->read != NULL);
- bread = client->handlers->read(client->handlers->transport_data, (uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE);
- if (bread < 0)
- {
- ipc_client_log(client, "crespo_ipc_rfs_client_recv: can't receive enough bytes from modem to process incoming response!");
+ if (client == NULL || client->handlers == NULL || client->handlers->read == NULL || response == NULL)
return -1;
- }
- if(modem_data.size <= 0 || modem_data.size >= MAX_MODEM_DATA_SIZE || modem_data.data == NULL)
- {
- ipc_client_log(client, "crespo_ipc_rfs_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
- return -1;
+ memset(&mio, 0, sizeof(struct modem_io));
+ mio.size = MODEM_DATA_SIZE;
+ mio.data = malloc(mio.size);
+
+ rc = client->handlers->read(client->handlers->transport_data, &mio, sizeof(struct modem_io) + mio.size);
+ if (rc < 0 || mio.data == NULL || mio.size <= 0) {
+ ipc_client_log(client, "Reading RFS data from the modem failed");
+ goto error;
}
- response->mseq = 0;
- response->aseq = modem_data.id;
+ memset(response, 0, sizeof(struct ipc_message_info));
+ response->aseq = mio.id;
response->group = IPC_GROUP_RFS;
- response->index = modem_data.cmd;
- response->type = 0;
- response->length = modem_data.size;
- response->data = NULL;
+ response->index = mio.cmd;
- if(response->length > 0)
- {
+ if (mio.size > 0) {
+ response->length = mio.size;
response->data = malloc(response->length);
- memcpy(response->data, (uint8_t *) modem_data.data, response->length);
+ memcpy(response->data, mio.data, response->length);
}
- free(modem_data.data);
-
ipc_client_log_recv(client, response, __func__);
- return 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (mio.data != NULL)
+ free(mio.data);
+
+ return rc;
}
int crespo_ipc_open(void *transport_data, int type)
@@ -458,10 +273,10 @@ int crespo_ipc_open(void *transport_data, int type)
switch(type)
{
case IPC_CLIENT_TYPE_FMT:
- fd = open("/dev/modem_fmt", O_RDWR | O_NOCTTY | O_NONBLOCK);
+ fd = open(MODEM_FMT_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
break;
case IPC_CLIENT_TYPE_RFS:
- fd = open("/dev/modem_rfs", O_RDWR | O_NOCTTY | O_NONBLOCK);
+ fd = open(MODEM_RFS_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
break;
default:
return -1;
@@ -489,6 +304,7 @@ int crespo_ipc_close(void *transport_data)
if (fd < 0)
return -1;
+ data->fd = -1;
close(fd);
return 0;
@@ -500,7 +316,7 @@ int crespo_ipc_read(void *transport_data, void *buffer, unsigned int length)
int fd;
int rc;
- if (transport_data == NULL)
+ if (transport_data == NULL || buffer == NULL || length == 0)
return -1;
data = (struct crespo_ipc_transport_data *) transport_data;
@@ -522,7 +338,7 @@ int crespo_ipc_write(void *transport_data, void *buffer, unsigned int length)
int fd;
int rc;
- if (transport_data == NULL)
+ if (transport_data == NULL || buffer == NULL || length == 0)
return -1;
data = (struct crespo_ipc_transport_data *) transport_data;
@@ -532,7 +348,7 @@ int crespo_ipc_write(void *transport_data, void *buffer, unsigned int length)
return -1;
rc = ioctl(fd, IOCTL_MODEM_SEND, buffer);
- if(rc < 0)
+ if (rc < 0)
return -1;
return 0;
@@ -563,21 +379,18 @@ int crespo_ipc_poll(void *transport_data, struct timeval *timeout)
int crespo_ipc_power_on(void *power_data)
{
- int fd=open("/dev/modem_ctl", O_RDWR);
+ int fd;
int rc;
-/*
- fd = open("/sys/devices/platform/modemctl/power_mode", O_RDWR);
- rc = write(fd, "1", 1);
-*/
-
- if(fd < 0)
+ fd = open(MODEM_CTL_DEVICE, O_RDWR);
+ if (fd < 0)
return -1;
rc = ioctl(fd, IOCTL_MODEM_START);
+
close(fd);
- if(rc < 0)
+ if (rc < 0)
return -1;
return 0;
@@ -585,21 +398,18 @@ int crespo_ipc_power_on(void *power_data)
int crespo_ipc_power_off(void *power_data)
{
- int fd=open("/dev/modem_ctl", O_RDWR);
+ int fd;
int rc;
-/*
- fd = open("/sys/devices/platform/modemctl/power_mode", O_RDWR);
- rc = write(fd, "0", 1);
-*/
-
- if(fd < 0)
+ fd = open(MODEM_CTL_DEVICE, O_RDWR);
+ if (fd < 0)
return -1;
rc = ioctl(fd, IOCTL_MODEM_OFF);
+
close(fd);
- if(rc < 0)
+ if (rc < 0)
return -1;
return 0;
@@ -626,7 +436,7 @@ int crespo_ipc_data_destroy(void *transport_data, void *power_data, void *gprs_d
return 0;
}
-char *crespo_2_6_35_ipc_gprs_get_iface(int cid)
+char *crespo_ipc_gprs_get_iface_single(int cid)
{
char *iface = NULL;
@@ -635,19 +445,7 @@ char *crespo_2_6_35_ipc_gprs_get_iface(int cid)
return iface;
}
-char *crespo_3_0_ipc_gprs_get_iface(int cid)
-{
- char *iface = NULL;
-
- if(cid > GPRS_IFACE_COUNT)
- return NULL;
-
- asprintf(&iface, "%s%d", GPRS_IFACE_PREFIX, cid - 1);
-
- return iface;
-}
-
-int crespo_2_6_35_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities)
+int crespo_ipc_gprs_get_capabilities_single(struct ipc_client_gprs_capabilities *capabilities)
{
if (capabilities == NULL)
return -1;
@@ -658,7 +456,19 @@ int crespo_2_6_35_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities
return 0;
}
-int crespo_3_0_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities)
+char *crespo_ipc_gprs_get_iface(int cid)
+{
+ char *iface = NULL;
+
+ if (cid > GPRS_IFACE_COUNT)
+ return NULL;
+
+ asprintf(&iface, "%s%d", GPRS_IFACE_PREFIX, cid - 1);
+
+ return iface;
+}
+
+int crespo_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities)
{
if (capabilities == NULL)
return -1;
@@ -698,14 +508,14 @@ struct ipc_handlers crespo_ipc_handlers = {
.data_destroy = crespo_ipc_data_destroy,
};
-struct ipc_gprs_specs crespo_2_6_35_ipc_gprs_specs = {
- .gprs_get_iface = crespo_2_6_35_ipc_gprs_get_iface,
- .gprs_get_capabilities = crespo_2_6_35_ipc_gprs_get_capabilities,
+struct ipc_gprs_specs crespo_ipc_gprs_specs_single = {
+ .gprs_get_iface = crespo_ipc_gprs_get_iface_single,
+ .gprs_get_capabilities = crespo_ipc_gprs_get_capabilities_single,
};
-struct ipc_gprs_specs crespo_3_0_ipc_gprs_specs = {
- .gprs_get_iface = crespo_3_0_ipc_gprs_get_iface,
- .gprs_get_capabilities = crespo_3_0_ipc_gprs_get_capabilities,
+struct ipc_gprs_specs crespo_ipc_gprs_specs = {
+ .gprs_get_iface = crespo_ipc_gprs_get_iface,
+ .gprs_get_capabilities = crespo_ipc_gprs_get_capabilities,
};
// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/crespo/crespo_ipc.h b/samsung-ipc/device/crespo/crespo_ipc.h
index f633d1b..1750d97 100644
--- a/samsung-ipc/device/crespo/crespo_ipc.h
+++ b/samsung-ipc/device/crespo/crespo_ipc.h
@@ -1,7 +1,7 @@
-/**
+/*
* This file is part of libsamsung-ipc.
*
- * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
+ * Copyright (C) 2011-2013 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
@@ -21,15 +21,18 @@
#ifndef __CRESPO_IPC_H__
#define __CRESPO_IPC_H__
-#define BOOTCORE_VERSION 0xf0
-#define PSI_MAGIC 0x30
-#define PSI_DATA_LEN 0x5000
-#define RADIO_IMG_SIZE 0xd80000
+#define MODEM_IMAGE_SIZE 0xD80000
+#define NV_DATA_OFFSET 0xD80000
+#define MODEM_DATA_SIZE 0x50000
-#define MAX_MODEM_DATA_SIZE 0x50000
+#define MODEM_IMAGE_DEVICE "/dev/mtd/mtd5ro"
+#define MODEM_SERIAL_DEVICE "/dev/s3c2410_serial3"
+#define MODEM_CTL_DEVICE "/dev/modem_ctl"
+#define MODEM_FMT_DEVICE "/dev/modem_fmt"
+#define MODEM_RFS_DEVICE "/dev/modem_rfs"
-#define GPRS_IFACE_PREFIX "rmnet"
-#define GPRS_IFACE_COUNT 3
+#define GPRS_IFACE_PREFIX "rmnet"
+#define GPRS_IFACE_COUNT 3
struct crespo_ipc_transport_data {
int fd;
diff --git a/samsung-ipc/device/xmm6160/xmm6160.c b/samsung-ipc/device/xmm6160/xmm6160.c
new file mode 100644
index 0000000..11e3ec5
--- /dev/null
+++ b/samsung-ipc/device/xmm6160/xmm6160.c
@@ -0,0 +1,304 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2011-2013 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 2 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 <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/select.h>
+
+#include <samsung-ipc.h>
+#include <util.h>
+
+#include "xmm6160.h"
+
+int xmm6160_psi_send(struct ipc_client *client, int serial_fd,
+ void *modem_image_data, int modem_image_size)
+{
+ char modem_at[] = MODEM_AT;
+ unsigned char version;
+ unsigned char info;
+ unsigned char psi_magic;
+ unsigned short psi_size;
+ unsigned char psi_crc;
+ unsigned char psi_ack;
+
+ struct termios termios;
+ struct timeval timeout;
+ fd_set fds;
+
+ unsigned char *p;
+ int length;
+ int rc;
+ int i;
+
+ if (client == NULL || serial_fd < 0 || modem_image_data == NULL || modem_image_size < MODEM_PSI_SIZE)
+ return -1;
+
+ tcgetattr(serial_fd, &termios);
+
+ cfmakeraw(&termios);
+ cfsetispeed(&termios, B115200);
+ cfsetospeed(&termios, B115200);
+
+ tcsetattr(serial_fd, TCSANOW, &termios);
+
+ length = strlen(modem_at);
+ for (i=0; i < MODEM_AT_COUNT; i++) {
+ rc = write(serial_fd, modem_at, length);
+ if (rc < length) {
+ ipc_client_log(client, "Writing AT in ASCII failed");
+ goto error;
+ }
+
+ usleep(50000);
+ }
+ ipc_client_log(client, "Wrote AT in ASCII");
+
+ usleep(50000);
+
+ version = 0;
+
+ rc = read(serial_fd, &version, sizeof(version));
+ if (rc < (int) sizeof(version)) {
+ ipc_client_log(client, "Reading bootcore version failed");
+ goto error;
+ }
+
+ if (version != MODEM_BOOTCORE_VERSION) {
+ ipc_client_log(client, "Read wrong bootcore version (0x%x)", version);
+ goto error;
+ }
+
+ ipc_client_log(client, "Read bootcore version (0x%x)", version);
+
+ rc = read(serial_fd, &info, sizeof(info));
+ if (rc < (int) sizeof(info)) {
+ ipc_client_log(client, "Reading info size failed");
+ goto error;
+ }
+ ipc_client_log(client, "Read info size (0x%x)", info);
+
+ psi_magic = MODEM_PSI_MAGIC;
+
+ rc = write(serial_fd, &psi_magic, sizeof(psi_magic));
+ if (rc < (int) sizeof(psi_magic)) {
+ ipc_client_log(client, "Writing PSI magic failed");
+ goto error;
+ }
+ ipc_client_log(client, "Wrote PSI magic (0x%x)", psi_magic);
+
+ psi_size = MODEM_PSI_SIZE;
+
+ rc = write(serial_fd, &psi_size, sizeof(psi_size));
+ if (rc < (int) sizeof(psi_size)) {
+ ipc_client_log(client, "Writing PSI size failed");
+ goto error;
+ }
+ ipc_client_log(client, "Wrote PSI size (0x%x)", psi_size);
+
+ FD_ZERO(&fds);
+ FD_SET(serial_fd, &fds);
+
+ timeout.tv_sec = 4;
+ timeout.tv_usec = 0;
+
+ p = (unsigned char *) modem_image_data;
+ psi_crc = 0;
+
+ for (i=0; i < MODEM_PSI_SIZE; i++) {
+ rc = select(serial_fd + 1, NULL, &fds, NULL, &timeout);
+ if (rc <= 0) {
+ ipc_client_log(client, "Writing PSI failed");
+ goto error;
+ }
+
+ rc = write(serial_fd, p, 1);
+ if (rc < 1) {
+ ipc_client_log(client, "Writing PSI failed");
+ goto error;
+ }
+
+ psi_crc ^= *p++;
+ }
+ ipc_client_log(client, "Wrote PSI, CRC is 0x%x", psi_crc);
+
+ rc = select(serial_fd + 1, NULL, &fds, NULL, &timeout);
+ if (rc <= 0) {
+ ipc_client_log(client, "Writing PSI crc failed");
+ goto error;
+ }
+
+ rc = write(serial_fd, &psi_crc, sizeof(psi_crc));
+ if (rc < (int) sizeof(psi_crc)) {
+ ipc_client_log(client, "Writing PSI crc failed");
+ goto error;
+ }
+ ipc_client_log(client, "Wrote PSI CRC (0x%x)", psi_crc);
+
+ timeout.tv_sec = 4;
+ timeout.tv_usec = 0;
+
+ i = 0;
+ do {
+ rc = select(serial_fd + 1, &fds, NULL, NULL, &timeout);
+ if (rc <= 0) {
+ ipc_client_log(client, "Reading PSI ACK failed");
+ goto error;
+ }
+
+ rc = read(serial_fd, &psi_ack, sizeof(psi_ack));
+ if (rc < (int) sizeof(psi_ack)) {
+ ipc_client_log(client, "Reading PSI ACK failed");
+ goto error;
+ }
+
+ if (i++ > 50) {
+ ipc_client_log(client, "Reading PSI ACK failed");
+ goto error;
+ }
+ } while (psi_ack != MODEM_PSI_ACK);
+ ipc_client_log(client, "Read PSI ACK (0x%x)", psi_ack);
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ return rc;
+}
+
+int xmm6160_modem_image_send(struct ipc_client *client, int device_fd,
+ void *device_address, void *modem_image_data, int modem_image_size, int modem_image_offset)
+{
+ int wc;
+
+ unsigned char *p;
+ int length;
+ int rc;
+ int i;
+
+ if (client == NULL || (device_fd < 0 && device_address == NULL) || modem_image_data == NULL || modem_image_size <= MODEM_PSI_SIZE)
+ return -1;
+
+ p = (unsigned char *) modem_image_data + MODEM_PSI_SIZE;
+ length = modem_image_size - MODEM_PSI_SIZE;
+
+ if (device_address != NULL) {
+ memcpy((void *) ((unsigned char *) device_address + modem_image_offset), p, length);
+ } else {
+ lseek(device_fd, modem_image_offset, SEEK_SET);
+
+ wc = 0;
+ while (wc < length) {
+ rc = write(device_fd, p, length - wc);
+ if (rc < 0) {
+ ipc_client_log(client, "Writing modem image failed");
+ goto error;
+ }
+
+ p += rc;
+ wc += rc;
+ }
+ }
+ ipc_client_log(client, "Wrote modem image");
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ return rc;
+}
+
+int xmm6160_nv_data_send(struct ipc_client *client, int device_fd,
+ void *device_address, int modem_image_offset)
+{
+ void *nv_data = NULL;
+ int wc;
+
+ unsigned char *p;
+ int length;
+ int rc;
+
+ if (client == NULL || (device_fd < 0 && device_address == NULL))
+ return -1;
+
+ rc = nv_data_check(client);
+ if (rc < 0) {
+ ipc_client_log(client, "Checking nv_data failed");
+ goto error;
+ }
+ ipc_client_log(client, "Checked nv_data");
+
+ rc = nv_data_md5_check(client);
+ if (rc < 0) {
+ ipc_client_log(client, "Checking nv_data md5 failed");
+ goto error;
+ }
+ ipc_client_log(client, "Checked nv_data md5");
+
+ nv_data = file_data_read(nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client));
+ if (nv_data == NULL) {
+ ipc_client_log(client, "Reading nv_data failed");
+ goto error;
+ }
+ ipc_client_log(client, "Read nv_data");
+
+ p = (unsigned char *) nv_data;
+ length = nv_data_size(client);
+
+ if (device_address != NULL) {
+ memcpy((void *) ((unsigned char *) device_address + modem_image_offset), p, length);
+ } else {
+ lseek(device_fd, modem_image_offset, SEEK_SET);
+
+ wc = 0;
+ while (wc < length) {
+ rc = write(device_fd, p, length - wc);
+ if (rc < 0) {
+ ipc_client_log(client, "Writing modem image failed");
+ goto error;
+ }
+
+ p += rc;
+ wc += rc;
+ }
+ }
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (nv_data != NULL)
+ free(nv_data);
+
+ return rc;
+}
+
+// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/xmm6160/xmm6160.h b/samsung-ipc/device/xmm6160/xmm6160.h
new file mode 100644
index 0000000..e48323d
--- /dev/null
+++ b/samsung-ipc/device/xmm6160/xmm6160.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2011-2013 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 2 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 <samsung-ipc.h>
+
+#ifndef __XMM6160_H__
+#define __XMM6160_H__
+
+#define MODEM_AT "AT"
+#define MODEM_AT_COUNT 20
+#define MODEM_PSI_SIZE 0x5000
+#define MODEM_PSI_MAGIC 0x30
+#define MODEM_PSI_ACK 0x01
+#define MODEM_BOOTCORE_VERSION 0xF0
+
+int xmm6160_psi_send(struct ipc_client *client, int serial_fd,
+ void *modem_image_data, int modem_image_size);
+int xmm6160_modem_image_send(struct ipc_client *client, int device_fd,
+ void *device_address, void *modem_image_data, int modem_image_size,int modem_image_offset);
+int xmm6160_nv_data_send(struct ipc_client *client, int device_fd,
+ void *device_address, int modem_image_offset);
+
+#endif
+
+// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/device/xmm6260/xmm6260_ipc.h b/samsung-ipc/device/xmm6260/xmm6260_ipc.h
index 588469d..632c300 100644
--- a/samsung-ipc/device/xmm6260/xmm6260_ipc.h
+++ b/samsung-ipc/device/xmm6260/xmm6260_ipc.h
@@ -23,6 +23,8 @@
* along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdint.h>
+
#ifndef __XMM6260_IPC_H__
#define __XMM6260_IPC_H__
diff --git a/samsung-ipc/ipc_devices.c b/samsung-ipc/ipc_devices.c
index 77b58dd..2bd436e 100644
--- a/samsung-ipc/ipc_devices.c
+++ b/samsung-ipc/ipc_devices.c
@@ -32,7 +32,7 @@ struct ipc_device_desc ipc_devices[] = {
.fmt_ops = &crespo_ipc_fmt_ops,
.rfs_ops = &crespo_ipc_rfs_ops,
.handlers = &crespo_ipc_handlers,
- .gprs_specs = &crespo_2_6_35_ipc_gprs_specs,
+ .gprs_specs = &crespo_ipc_gprs_specs_single,
.nv_data_specs = NULL,
},
{
@@ -42,7 +42,7 @@ struct ipc_device_desc ipc_devices[] = {
.fmt_ops = &crespo_ipc_fmt_ops,
.rfs_ops = &crespo_ipc_rfs_ops,
.handlers = &crespo_ipc_handlers,
- .gprs_specs = &crespo_3_0_ipc_gprs_specs,
+ .gprs_specs = &crespo_ipc_gprs_specs,
.nv_data_specs = NULL,
},
{
diff --git a/samsung-ipc/ipc_devices.h b/samsung-ipc/ipc_devices.h
index 17c16f1..b8f4007 100644
--- a/samsung-ipc/ipc_devices.h
+++ b/samsung-ipc/ipc_devices.h
@@ -42,8 +42,8 @@ extern int ipc_devices_count;
extern struct ipc_ops crespo_ipc_fmt_ops;
extern struct ipc_ops crespo_ipc_rfs_ops;
extern struct ipc_handlers crespo_ipc_handlers;
-extern struct ipc_gprs_specs crespo_2_6_35_ipc_gprs_specs;
-extern struct ipc_gprs_specs crespo_3_0_ipc_gprs_specs;
+extern struct ipc_gprs_specs crespo_ipc_gprs_specs_single;
+extern struct ipc_gprs_specs crespo_ipc_gprs_specs;
/* aries */
extern struct ipc_ops aries_ipc_fmt_ops;