diff options
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | include/radio.h | 10 | ||||
-rw-r--r-- | samsung-ipc-1.0.pc.in | 13 | ||||
-rw-r--r-- | samsung-ipc/crespo_ipc.c | 75 | ||||
-rw-r--r-- | samsung-ipc/h1_ipc.c | 6 | ||||
-rw-r--r-- | samsung-ipc/ipc.c | 12 | ||||
-rw-r--r-- | samsung-ipc/ipc_private.h | 14 | ||||
-rw-r--r-- | samsung-ipc/test.c | 2 | ||||
-rw-r--r-- | vapi/samsung-ipc-1.0.vapi | 89 |
10 files changed, 193 insertions, 39 deletions
diff --git a/Makefile.am b/Makefile.am index 7da6a3d..696453e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,8 +5,18 @@ SUBDIRS = \ include \ $(NULL) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = samsung-ipc-1.0.pc + EXTRA_DIST = \ MAINTAINERS \ + samsung-ipc-1.0.pc \ + $(NULL) + +vapidir = $(datadir)/vala/vapi + +dist_vapi_DATA = \ + vapi/samsung-ipc-1.0.vapi \ $(NULL) MAINTAINERCLEANFILES = \ diff --git a/configure.ac b/configure.ac index 555fef0..7719ea8 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,7 @@ PKG_PROG_PKG_CONFIG AC_CONFIG_FILES([ Makefile + samsung-ipc-1.0.pc include/Makefile samsung-ipc/Makefile ]) diff --git a/include/radio.h b/include/radio.h index 24c770b..209a1ef 100644 --- a/include/radio.h +++ b/include/radio.h @@ -55,11 +55,13 @@ struct ipc_response { }; int ipc_init(int client_type); -int ipc_open(); -int ipc_close(); +int ipc_boostrap(void); +int ipc_open(void); +int ipc_close(void); +int ipc_fd_get(void); -void ipc_power_on(); -void ipc_power_off(); +void ipc_power_on(void); +void ipc_power_off(void); void ipc_send(struct ipc_request *request); int ipc_recv(struct ipc_response *response); diff --git a/samsung-ipc-1.0.pc.in b/samsung-ipc-1.0.pc.in new file mode 100644 index 0000000..8f22109 --- /dev/null +++ b/samsung-ipc-1.0.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ + +Name: libsamsung-ipc +Description: A implemenation of the protocol to speak with modems found in most Samsung devices +Version: @VERSION@ +Requires: +Libs: -L${libdir} -lsamsung-ipc +Cflags: -I${includedir}/samsung-ipc-1.0 diff --git a/samsung-ipc/crespo_ipc.c b/samsung-ipc/crespo_ipc.c index 9f9a81a..02f150f 100644 --- a/samsung-ipc/crespo_ipc.c +++ b/samsung-ipc/crespo_ipc.c @@ -136,7 +136,7 @@ error: return NULL; } -int crespo_ipc_open(void) +int crespo_ipc_bootstrap(void) { /* Control variables. */ int boot_tries_count=0; @@ -166,21 +166,21 @@ int crespo_ipc_open(void) uint8_t *data_p; int i; - printf("crespo_ipc_open: enter\n"); + printf("crespo_ipc_bootstrap: enter\n"); boot_loop_start: if(boot_tries_count > 5) { - printf("crespo_ipc_open: boot has failed too many times.\n"); + printf("crespo_ipc_bootstrap: boot has failed too many times.\n"); goto error; } /* Read the radio.img image. */ - printf("crespo_ipc_open: reading radio image\n"); + printf("crespo_ipc_bootstrap: reading radio image\n"); radio_img_p=mtd_read("/dev/mtd/mtd5ro", RADIO_IMG_SIZE, 0x1000); - printf("crespo_ipc_open: radio image read\n"); + printf("crespo_ipc_bootstrap: radio image read\n"); - printf("crespo_ipc_open: open modem_ctl\n"); + printf("crespo_ipc_bootstrap: open modem_ctl\n"); modem_ctl_fd=open("/dev/modem_ctl", O_RDWR | O_NDELAY); if(modem_ctl_fd < 0) goto error_loop; @@ -189,13 +189,13 @@ boot_loop_start: ioctl(modem_ctl_fd, IOCTL_MODEM_RESET); usleep(400000); - printf("crespo_ipc_open: open s3c2410_serial3\n"); + printf("crespo_ipc_bootstrap: open s3c2410_serial3\n"); s3c2410_serial3_fd=open("/dev/s3c2410_serial3", O_RDWR | O_NDELAY); if(s3c2410_serial3_fd < 0) goto error_loop; /* Setup the s3c2410 serial. */ - printf("crespo_ipc_open: setup s3c2410_serial3\n"); + printf("crespo_ipc_bootstrap: setup s3c2410_serial3\n"); tcgetattr(s3c2410_serial3_fd, &termios); cfmakeraw(&termios); @@ -211,31 +211,31 @@ boot_loop_start: tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios); //FIXME /* Send 'AT' in ASCII. */ - printf("crespo_ipc_open: sending AT in ASCII\n"); + printf("crespo_ipc_bootstrap: sending AT in ASCII\n"); for(i=0 ; i < 20 ; i++) { write(s3c2410_serial3_fd, "AT", 2); usleep(50000); } - printf("crespo_ipc_open: sending AT in ASCII done\n"); + printf("crespo_ipc_bootstrap: sending AT in ASCII done\n"); usleep(50000); //FIXME /* Get and check bootcore version. */ read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version)); - printf("crespo_ipc_open: got bootcore version: 0x%x\n", bootcore_version); + printf("crespo_ipc_bootstrap: got bootcore version: 0x%x\n", bootcore_version); if(bootcore_version != BOOTCORE_VERSION) goto error_loop; /* Get info_size. */ read(s3c2410_serial3_fd, &info_size, sizeof(info_size)); - printf("crespo_ipc_open: got info_size: 0x%x\n", info_size); + printf("crespo_ipc_bootstrap: got info_size: 0x%x\n", info_size); /* Send PSI magic. */ data=PSI_MAGIC; write(s3c2410_serial3_fd, &data, sizeof(data)); - printf("crespo_ipc_open: sent PSI_MAGIC (0x%x)\n", PSI_MAGIC); + printf("crespo_ipc_bootstrap: sent PSI_MAGIC (0x%x)\n", PSI_MAGIC); /* Send PSI data len. */ data_16=PSI_DATA_LEN; @@ -246,7 +246,7 @@ boot_loop_start: write(s3c2410_serial3_fd, data_p, 1); data_p++; } - printf("crespo_ipc_open: sent PSI_DATA_LEN (0x%x)\n", PSI_DATA_LEN); + printf("crespo_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)\n", PSI_DATA_LEN); /* Write the first part of modem.img. */ FD_ZERO(&fds); @@ -257,13 +257,13 @@ boot_loop_start: data_p=radio_img_p; - printf("crespo_ipc_open: sending the first part of radio.img\n"); + printf("crespo_ipc_bootstrap: sending the first part of radio.img\n"); for(i=0 ; i < PSI_DATA_LEN ; i++) { if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) { - printf("crespo_ipc_open: select timeout passed\n"); + printf("crespo_ipc_bootstrap: select timeout passed\n"); goto error_loop; } @@ -273,24 +273,24 @@ boot_loop_start: data_p++; } - printf("crespo_ipc_open: first part of radio.img sent; crc_byte is 0x%x\n", crc_byte); + printf("crespo_ipc_bootstrap: first part of radio.img sent; crc_byte is 0x%x\n", crc_byte); if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) { - printf("crespo_ipc_open: select timeout passed\n"); + printf("crespo_ipc_bootstrap: select timeout passed\n"); goto error_loop; } write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte)); - printf("crespo_ipc_open: crc_byte sent\n"); + printf("crespo_ipc_bootstrap: crc_byte sent\n"); data=0; for(i=0 ; data != 0x01 ; i++) { if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0) { - printf("crespo_ipc_open: select timeout passed\n"); + printf("crespo_ipc_bootstrap: select timeout passed\n"); goto error_loop; } @@ -298,15 +298,15 @@ boot_loop_start: if(i > 50) { - printf("crespo_ipc_open: fairly too much attempts to get ACK\n"); + printf("crespo_ipc_bootstrap: fairly too much attempts to get ACK\n"); goto error_loop; } } - printf("crespo_ipc_open: close s3c2410_serial3\n"); + printf("crespo_ipc_bootstrap: close s3c2410_serial3\n"); close(s3c2410_serial3_fd); - printf("crespo_ipc_open: writing the rest of radio.img to modem_ctl.\n"); + printf("crespo_ipc_bootstrap: writing the rest of radio.img to modem_ctl.\n"); /* Seek to the begining of modem_ctl_fd (should already be so). */ lseek(modem_ctl_fd, 0, SEEK_SET); @@ -322,7 +322,7 @@ boot_loop_start: { if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) { - printf("crespo_ipc_open: select timeout passed\n"); + printf("crespo_ipc_bootstrap: select timeout passed\n"); goto error_loop; } @@ -341,7 +341,7 @@ boot_loop_start: nv_data_md5_check(); /* Write nv_data.bin to modem_ctl. */ - printf("crespo_ipc_open: write nv_data to modem_ctl\n"); + printf("crespo_ipc_bootstrap: write nv_data to modem_ctl\n"); nv_data_p=file_read("/efs/nv_data.bin", NV_DATA_SIZE, 1024); data_p=nv_data_p; @@ -356,9 +356,6 @@ boot_loop_start: free(nv_data_p); - modem_fmt_fd=open("/dev/modem_fmt", O_RDWR | O_NDELAY); - modem_rfs_fd=open("/dev/modem_rfs", O_RDWR | O_NDELAY); - rc=0; goto exit; @@ -373,14 +370,25 @@ error: printf("%s: something went wrong\n", __func__); rc=1; exit: - printf("crespo_ipc_open: exit\n"); + printf("crespo_ipc_bootstrap: exit\n"); return rc; } +int crespo_ipc_open(void) +{ + modem_fmt_fd = open("/dev/modem_fmt", O_RDWR | O_NDELAY); +#if 0 + modem_rfs_fd=open("/dev/modem_rfs", O_RDWR | O_NDELAY); +#endif + return modem_fmt_fd > 0 ? 0 : -1; +} + int crespo_ipc_close(void) { close(modem_fmt_fd); +#if 0 close(modem_rfs_fd); +#endif close(modem_ctl_fd); return 0; @@ -396,6 +404,11 @@ void crespo_ipc_power_off(void) ioctl(modem_ctl_fd, IOCTL_MODEM_OFF); } +int crespo_ipc_fd_get(void) +{ + return modem_fmt_fd; +} + void crespo_ipc_send(struct ipc_request *request) { struct modem_io modem_data; @@ -459,6 +472,8 @@ recv_loop_start: FD_ZERO(&fds); FD_SET(modem_fmt_fd, &fds); + +#if 0 FD_SET(modem_rfs_fd, &fds); select(FD_SETSIZE, &fds, NULL, NULL, NULL); @@ -473,6 +488,7 @@ recv_loop_start: goto recv_loop_start; return 0; } +#endif if(FD_ISSET(modem_fmt_fd, &fds)) { @@ -514,6 +530,7 @@ recv_loop_start: struct ipc_ops crespo_ipc_ops = { .open = crespo_ipc_open, + .bootstrap = crespo_ipc_bootstrap, .close = crespo_ipc_close, .power_on = crespo_ipc_power_on, .power_off = crespo_ipc_power_off, diff --git a/samsung-ipc/h1_ipc.c b/samsung-ipc/h1_ipc.c index 119ef5b..65f48bb 100644 --- a/samsung-ipc/h1_ipc.c +++ b/samsung-ipc/h1_ipc.c @@ -53,6 +53,11 @@ int h1_ipc_close() return 1; } +int h1_ipc_fd_get() +{ + return fd; +} + void h1_ipc_power_on() { ioctl(fd, IOCTL_PHONE_ON); @@ -139,4 +144,5 @@ struct ipc_ops h1_ipc_ops = { .power_off = h1_ipc_power_off, .send = h1_ipc_send, .recv = h1_ipc_recv, + .fd_get = h1_ipc_fd_get, }; diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index e25ba7e..0d5c359 100644 --- a/samsung-ipc/ipc.c +++ b/samsung-ipc/ipc.c @@ -51,6 +51,11 @@ int ipc_init(int client_type) return rc; } +int ipc_bootstrap(void) +{ + return ops != NULL && ops->bootstrap != NULL ? ops->bootstrap() : -1; +} + int ipc_open(void) { return ops != NULL && ops->open != NULL ? ops->open() : -1; @@ -79,6 +84,13 @@ void ipc_send(struct ipc_request *request) ops->send(request); } +int ipc_fd_get() +{ + if (ops != NULL && ops->fd_get != NULL) + return ops->fd_get(); + return -1; +} + /* Convenience functions for ipc_send */ inline void ipc_msg_send_get(const int command, unsigned char aseq) { diff --git a/samsung-ipc/ipc_private.h b/samsung-ipc/ipc_private.h index 2dbf2c3..f439719 100644 --- a/samsung-ipc/ipc_private.h +++ b/samsung-ipc/ipc_private.h @@ -22,12 +22,14 @@ #define __IPC_PRIVATE_H__ struct ipc_ops { - int (*open)(void); - int (*close)(void); - void (*power_on)(void); - void (*power_off)(void); - int (*send)(struct ipc_request*); - int (*recv)(struct ipc_response*); + int (*bootstrap)(void); + int (*open)(void); + int (*close)(void); + void (*power_on)(void); + void (*power_off)(void); + int (*send)(struct ipc_request*); + int (*recv)(struct ipc_response*); + int (*fd_get)(void); }; #endif diff --git a/samsung-ipc/test.c b/samsung-ipc/test.c index b91810d..ddfc530 100644 --- a/samsung-ipc/test.c +++ b/samsung-ipc/test.c @@ -40,6 +40,8 @@ int main(int argc, char *argv[]) struct ipc_response response; int error; + ipc_init(IPC_CLIENT_TYPE_CRESPO); + printf("ipc_open\n"); error = ipc_open(); diff --git a/vapi/samsung-ipc-1.0.vapi b/vapi/samsung-ipc-1.0.vapi new file mode 100644 index 0000000..b4df9f8 --- /dev/null +++ b/vapi/samsung-ipc-1.0.vapi @@ -0,0 +1,89 @@ +/* + * samsung-ipc-1.0.vapi + * + * Copyright (C) 2011 Simon Busch <morphis@gravedo.de> + * + * This program 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. + + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +namespace SamsungIpc +{ + [CCode (cname = "int", cprefix = "IPC_CLIENT_TYPE_", has_type_id = false, cheader_filename = "radio.h")] + public enum ClientType + { + CRESPO, + H1, + } + + [CCode (cname = "struct ipc_header", cheader_filename = "radio.h")] + public struct Header + { + public uint16 length; + public uint8 mseq; + public uint8 aseq; + public uint8 group; + public uint8 index; + public uint8 type; + } + + [CCode (cname = "struct ipc_request", cheader_filename = "radio.h")] + public struct Request + { + public uint8 mseq; + public uint8 aseq; + public uint8 group; + public uint8 index; + public uint8 type; + public uint32 length; + public uint8[] data; + } + + [CCode (cname = "struct ipc_response", cheader_filename = "radio.h")] + public struct Response + { + public uint8 mseq; + public uint8 aseq; + public uint16 command; + public uint8 type; + public uint32 length; + public uint8[] data; + } + + [CCode (cname = "ipc_init", cheader_filename = "radio.h")] + public int init(ClientType type); + [CCode (cname = "ipc_bootstrap", cheader_filename = "radio.h")] + public int bootstrap(); + [CCode (cname = "ipc_open", cheader_filename = "radio.h")] + public void open(); + [CCode (cname = "ipc_close", cheader_filename = "radio.h")] + public void close(); + [CCode (cname = "ipc_fd_get", cheader_filename = "radio.h")] + public int fd_get(); + [CCode (cname = "ipc_power_on", cheader_filename = "radio.h")] + public void power_on(); + [CCode (cname = "ipc_power_off", cheader_filename = "radio.h")] + public void power_off(); + [CCode (cname = "ipc_send", cheader_filename = "radio.h")] + public void send(Request request); + [CCode (cname = "ipc_recv", cheader_filename = "radio.h")] + public int recv(Response response); + [CCode (cname = "ipc_msg_send", cheader_filename = "radio.h")] + public void message_send(int command, int type, uint8 data, int length, uint8 mseq); + [CCode (cname = "ipc_msg_send_get", cheader_filename = "radio.h")] + public void message_send_get(int command, uint8 aseq); + [CCode (cname = "ipc_msg_send_exec", cheader_filename = "radio.h")] + public void message_send_exec(int command, uint8 aseq); +} |