diff options
-rw-r--r-- | include/call.h | 4 | ||||
-rw-r--r-- | include/gprs.h | 73 | ||||
-rw-r--r-- | include/radio.h | 14 | ||||
-rw-r--r-- | include/rfs.h | 4 | ||||
-rw-r--r-- | samsung-ipc/device/aries/aries_ipc.c | 28 | ||||
-rw-r--r-- | samsung-ipc/device/aries/aries_ipc.h | 3 | ||||
-rw-r--r-- | samsung-ipc/device/crespo/crespo_ipc.c | 101 | ||||
-rw-r--r-- | samsung-ipc/device/crespo/crespo_ipc.h | 2 | ||||
-rw-r--r-- | samsung-ipc/device/galaxys2/galaxys2_loader.c | 9 | ||||
-rw-r--r-- | samsung-ipc/device/h1/h1_ipc.c | 4 | ||||
-rw-r--r-- | samsung-ipc/device/maguro/maguro_loader.c | 16 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/xmm6260_ipc.c | 17 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/xmm6260_ipc.h | 11 | ||||
-rw-r--r-- | samsung-ipc/gprs.c | 38 | ||||
-rw-r--r-- | samsung-ipc/ipc.c | 8 | ||||
-rw-r--r-- | samsung-ipc/ipc_private.h | 7 | ||||
-rw-r--r-- | samsung-ipc/ipc_util.c | 34 | ||||
-rw-r--r-- | samsung-ipc/rfs.c | 257 | ||||
-rw-r--r-- | vapi/samsung-ipc-1.0.vapi | 117 |
19 files changed, 526 insertions, 221 deletions
diff --git a/include/call.h b/include/call.h index 8536b28..94b9565 100644 --- a/include/call.h +++ b/include/call.h @@ -64,6 +64,10 @@ #define IPC_CALL_LIST_ENTRY_STATE_INCOMING 0x05 #define IPC_CALL_LIST_ENTRY_STATE_WAITING 0x06 +#define IPC_CALL_END_CAUSE_NORMAL 0x05 +#define IPC_CALL_END_CAUSE_REJECTED 0x2F +#define IPC_CALL_END_CAUSE_UNSPECIFIED 0x10 + #define IPC_CALL_TERM_MO 0x01 #define IPC_CALL_TERM_MT 0x02 diff --git a/include/gprs.h b/include/gprs.h index 600ad2e..1f3f99a 100644 --- a/include/gprs.h +++ b/include/gprs.h @@ -30,7 +30,6 @@ #define IPC_GPRS_MS_CLASS 0x0D07 #define IPC_GPRS_3G_QUAL_SERVICE_PROFILE 0x0D08 #define IPC_GPRS_IP_CONFIGURATION 0x0D09 -#define IPC_GPRS_PORT_LIST 0x0D11 #define IPC_GPRS_DEFINE_SEC_PDP_CONTEXT 0x0D0A #define IPC_GPRS_TFT 0x0D0B #define IPC_GPRS_HSDPA_STATUS 0x0D0C @@ -38,20 +37,54 @@ #define IPC_GPRS_DATA_DORMANT 0x0D0E #define IPC_GPRS_DUN_PIN_CTRL 0x0D0F #define IPC_GPRS_CALL_STATUS 0x0D10 +#define IPC_GPRS_PORT_LIST 0x0D11 -#define IPC_GPRS_CALL_STATUS_TYPE_ON 0x0 -#define IPC_GPRS_CALL_STATUS_TYPE_OFF 0x3 +#define IPC_GPRS_STATE_NOT_ENABLED 0x00 +#define IPC_GPRS_STATE_ENABLED 0x01 +#define IPC_GPRS_STATE_DISABLED 0x03 -#define IPC_GPRS_ERROR_UNAVAILABLE 0x94 -#define IPC_GPRS_ERROR_NOT_SUBSCRIBED 0x0B +#define IPC_GPRS_FAIL_INSUFFICIENT_RESOURCES 0x0004 +#define IPC_GPRS_FAIL_MISSING_UKNOWN_APN 0x0005 +#define IPC_GPRS_FAIL_UNKNOWN_PDP_ADDRESS_TYPE 0x0006 +#define IPC_GPRS_FAIL_USER_AUTHENTICATION 0x0007 +#define IPC_GPRS_FAIL_ACTIVATION_REJECT_GGSN 0x0008 +#define IPC_GPRS_FAIL_ACTIVATION_REJECT_UNSPECIFIED 0x0009 +#define IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUPPORTED 0x000A +#define IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED 0x000B +#define IPC_GPRS_FAIL_SERVICE_OPTION_OUT_OF_ORDER 0x000C +#define IPC_GPRS_FAIL_NSAPI_IN_USE 0x000D + +#define IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT 3 struct ipc_gprs_define_pdp_context { - unsigned char unk0[3]; + unsigned char enable; + unsigned char cid; + unsigned char unk; unsigned char apn[124]; }; +struct ipc_gprs_pdp_context_set { + unsigned char enable; + unsigned char cid; + unsigned char unk0[4]; + unsigned char username[32]; + unsigned char password[32]; + unsigned char unk1[32]; + unsigned char unk2; +}; + +struct ipc_gprs_pdp_context_get_desc { + unsigned char cid; + unsigned char state; +}; + +struct ipc_gprs_pdp_context_get { + unsigned char unk; + struct ipc_gprs_pdp_context_get_desc desc[IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT]; +}; + struct ipc_gprs_ip_configuration { - unsigned char unk0; + unsigned char cid; unsigned char field_flag; unsigned char unk1; unsigned char ip[4]; @@ -62,34 +95,24 @@ struct ipc_gprs_ip_configuration { unsigned char unk2[4]; }; -struct ipc_gprs_ip_configuration_response { - unsigned char unk0[376]; -}; - struct ipc_gprs_call_status { unsigned char cid; - unsigned char state; // IPC_GPRS_CALL_STATUS_TYPE_... - unsigned short reason; + unsigned char state; + unsigned short fail_cause; }; struct ipc_gprs_hsdpa_status { unsigned char unk; }; -struct ipc_gprs_pdp_context { - unsigned char unk0[6]; - unsigned char username[32]; - unsigned char password[32]; - unsigned char unk1[32]; - unsigned char unk2; -}; - struct ipc_gprs_ps { unsigned char unk[2]; }; struct ipc_gprs_current_session_data_counter { - unsigned char unk[9]; + unsigned char cid; + unsigned int rx_count; + unsigned int tx_count; }; struct ipc_gprs_port_list { @@ -97,8 +120,10 @@ struct ipc_gprs_port_list { }; void ipc_gprs_port_list_setup(struct ipc_gprs_port_list *message); -void ipc_gprs_pdp_context_setup(struct ipc_gprs_pdp_context *message, int activate, char *username, char *password); -void ipc_gprs_define_pdp_context_setup(struct ipc_gprs_define_pdp_context *message, char *apn); +void ipc_gprs_pdp_context_setup(struct ipc_gprs_pdp_context_set *message, + unsigned char cid, int enable, char *username, char *password); +void ipc_gprs_define_pdp_context_setup(struct ipc_gprs_define_pdp_context *message, + unsigned char cid, int enable, char *apn); #endif diff --git a/include/radio.h b/include/radio.h index 1e58d5b..c107dba 100644 --- a/include/radio.h +++ b/include/radio.h @@ -71,6 +71,7 @@ int ipc_client_set_handlers(struct ipc_client *client, struct ipc_handlers *hand int ipc_client_set_io_handlers(struct ipc_client *client, ipc_io_handler_cb read, void *read_data, ipc_io_handler_cb write, void *write_data); + int ipc_client_set_handlers_common_data(struct ipc_client *client, void *data); void *ipc_client_get_handlers_common_data(struct ipc_client *client); int ipc_client_create_handlers_common_data(struct ipc_client *client); @@ -86,7 +87,7 @@ int ipc_client_power_off(struct ipc_client *client); int ipc_client_gprs_handlers_available(struct ipc_client *client); int ipc_client_gprs_activate(struct ipc_client *client); int ipc_client_gprs_deactivate(struct ipc_client *client); -int ipc_client_gprs_get_iface(struct ipc_client *client, char **iface); +int ipc_client_gprs_get_iface(struct ipc_client *client, char **iface, int cid); int ipc_client_gprs_get_capabilities(struct ipc_client *client, struct ipc_client_gprs_capabilities *cap); int ipc_client_recv(struct ipc_client *client, struct ipc_message_info *response); @@ -99,15 +100,16 @@ void ipc_client_send_exec(struct ipc_client *client, const unsigned short comman /* Utility functions */ void ipc_client_log_recv(struct ipc_client *client, - struct ipc_message_info *response, char *prefix); + struct ipc_message_info *response, const char *prefix); void ipc_client_log_send(struct ipc_client *client, - struct ipc_message_info *request, char *prefix); + struct ipc_message_info *request, const char *prefix); const char *ipc_response_type_to_str(int type); const char *ipc_request_type_to_str(int type); const char *ipc_command_to_str(int command); -void ipc_hex_dump(struct ipc_client *client, void *data, int size); -void *ipc_mtd_read(struct ipc_client *client, char *mtd_name, int size, int block_size); -void *ipc_file_read(struct ipc_client *client, char *file_name, int size, int block_size); + +void ipc_client_hex_dump(struct ipc_client *client, void *data, int size); +void *ipc_client_mtd_read(struct ipc_client *client, char *mtd_name, int size, int block_size); +void *ipc_client_file_read(struct ipc_client *client, char *file_name, int size, int block_size); #endif diff --git a/include/rfs.h b/include/rfs.h index 6c2fa63..f9da1e8 100644 --- a/include/rfs.h +++ b/include/rfs.h @@ -63,8 +63,8 @@ void nv_data_md5_compute(void *data_p, int size, char *secret, void *hash); void nv_data_md5_generate(struct ipc_client *client); 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); +int nv_data_check(struct ipc_client *client); +int nv_data_md5_check(struct ipc_client *client); int nv_data_read(struct ipc_client *client, int offset, int length, char *buf); int nv_data_write(struct ipc_client *client, int offset, int length, char *buf); diff --git a/samsung-ipc/device/aries/aries_ipc.c b/samsung-ipc/device/aries/aries_ipc.c index f49754c..3e60134 100644 --- a/samsung-ipc/device/aries/aries_ipc.c +++ b/samsung-ipc/device/aries/aries_ipc.c @@ -137,7 +137,7 @@ int aries_modem_bootstrap(struct ipc_client *client) /* 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); + 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, "aries_ipc_bootstrap: open onedram"); @@ -348,15 +348,17 @@ int aries_modem_bootstrap(struct ipc_client *client) /* nv_data part. */ /* Check if all the nv_data files are ok. */ - nv_data_check(client); + if (nv_data_check(client) < 0) + goto error; /* Check if the MD5 is ok. */ - nv_data_md5_check(client); + if (nv_data_md5_check(client) < 0) + goto error; /* 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, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client)); + 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; @@ -831,7 +833,7 @@ int aries_ipc_gprs_deactivate(void *data) return 0; } -int aries_ipc_gprs_get_iface(char **iface) +int aries_ipc_gprs_get_iface(char **iface, int cid) { struct ifreq ifr; int fd; @@ -842,18 +844,20 @@ int aries_ipc_gprs_get_iface(char **iface) fd = socket(AF_PHONET, SOCK_DGRAM, 0); - for(i=0 ; i < 3 ; i++) { - sprintf(ifr.ifr_name, "pdp%d", 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) { - *iface=malloc(strlen(ifr.ifr_name) + 1); - memcpy((void *) *iface, ifr.ifr_name, strlen(ifr.ifr_name) + 1); + if(rc < 0 || ifr.ifr_flags & IFF_UP) { + continue; + } else { + asprintf(iface, "%s%d", GPRS_IFACE_PREFIX, i); return 0; } - } + *iface = NULL; + return -1; } @@ -863,7 +867,7 @@ int aries_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *cap) return -1; cap->port_list = 1; - cap->cid_max = 3; + cap->cid_max = GPRS_IFACE_COUNT; return 0; } diff --git a/samsung-ipc/device/aries/aries_ipc.h b/samsung-ipc/device/aries/aries_ipc.h index 82c7286..7f1420e 100644 --- a/samsung-ipc/device/aries/aries_ipc.h +++ b/samsung-ipc/device/aries/aries_ipc.h @@ -41,6 +41,9 @@ #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); diff --git a/samsung-ipc/device/crespo/crespo_ipc.c b/samsung-ipc/device/crespo/crespo_ipc.c index 46c5c05..83e7877 100644 --- a/samsung-ipc/device/crespo/crespo_ipc.c +++ b/samsung-ipc/device/crespo/crespo_ipc.c @@ -76,9 +76,9 @@ int crespo_modem_bootstrap(struct ipc_client *client) /* Read the radio.img image. */ ipc_client_log(client, "crespo_ipc_bootstrap: reading radio image"); - radio_img_p = ipc_mtd_read(client, "/dev/mtd/mtd5ro", RADIO_IMG_SIZE, 0x1000); + radio_img_p = ipc_client_mtd_read(client, "/dev/mtd/mtd5ro", RADIO_IMG_SIZE, 0x1000); if (radio_img_p == NULL) { - radio_img_p = ipc_mtd_read(client, "/dev/mtd5ro", RADIO_IMG_SIZE, 0x1000); + radio_img_p = ipc_client_mtd_read(client, "/dev/mtd5ro", RADIO_IMG_SIZE, 0x1000); if (radio_img_p == NULL) goto error; } @@ -90,7 +90,10 @@ int crespo_modem_bootstrap(struct ipc_client *client) goto error; /* Reset the modem before init to send the first part of modem.img. */ - ioctl(modem_ctl_fd, IOCTL_MODEM_RESET); + rc = ioctl(modem_ctl_fd, IOCTL_MODEM_RESET); + if (rc < 0) + goto error; + usleep(400000); ipc_client_log(client, "crespo_ipc_bootstrap: open s3c2410_serial3"); @@ -120,28 +123,40 @@ int crespo_modem_bootstrap(struct ipc_client *client) usleep(50000); //FIXME /* Get and check bootcore version. */ - read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version)); + rc = read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version)); + if (rc < 0) + 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. */ - read(s3c2410_serial3_fd, &info_size, sizeof(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; - write(s3c2410_serial3_fd, &data, sizeof(data)); + 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; + data_16 = PSI_DATA_LEN; + data_p = (uint8_t *)&data_16; for(i=0 ; i < 2 ; i++) { - write(s3c2410_serial3_fd, data_p, 1); + 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); @@ -150,49 +165,55 @@ int crespo_modem_bootstrap(struct ipc_client *client) FD_ZERO(&fds); FD_SET(s3c2410_serial3_fd, &fds); - timeout.tv_sec=4; - timeout.tv_usec=0; + timeout.tv_sec = 4; + timeout.tv_usec = 0; - data_p=radio_img_p; + 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++) + for (i=0 ; i < PSI_DATA_LEN ; i++) { - if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) + if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) { ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed"); goto error; } - write(s3c2410_serial3_fd, data_p, 1); - crc_byte=crc_byte ^ *data_p; + 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) + if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) { ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed"); goto error; } - write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte)); + rc = write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte)); + if (rc < 0) + goto error; ipc_client_log(client, "crespo_ipc_bootstrap: crc_byte sent"); data = 0; - for(i = 0 ; data != 0x01 ; i++) + for (i = 0 ; data != 0x01 ; i++) { - if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0) + if (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0) { ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed"); goto error; } - read(s3c2410_serial3_fd, &data, sizeof(data)); + rc = read(s3c2410_serial3_fd, &data, sizeof(data)); + if (rc < 0) + goto error; if(i > 50) { @@ -209,22 +230,25 @@ int crespo_modem_bootstrap(struct ipc_client *client) lseek(modem_ctl_fd, 0, SEEK_SET); /* Pointer to the remaining part of radio.img. */ - data_p=radio_img_p + PSI_DATA_LEN; + 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++) + for (i=0 ; i < (RADIO_IMG_SIZE - PSI_DATA_LEN) / block_size ; i++) { - if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) + if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0) { ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed"); goto error; } - write(modem_ctl_fd, data_p, block_size); + rc = write(modem_ctl_fd, data_p, block_size); + if (rc < 0) + goto error; + data_p += block_size; } @@ -233,29 +257,33 @@ int crespo_modem_bootstrap(struct ipc_client *client) /* nv_data part. */ /* Check if all the nv_data files are ok. */ - nv_data_check(client); + if (nv_data_check(client) < 0) + goto error; /* Check if the MD5 is ok. */ - nv_data_md5_check(client); + 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_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client)); + 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; + data_p = nv_data_p; lseek(modem_ctl_fd, RADIO_IMG_SIZE, SEEK_SET); for(i=0 ; i < 2 ; i++) { - write(modem_ctl_fd, data_p, nv_data_size(client) / 2); + 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); rc = 0; @@ -425,9 +453,8 @@ int crespo_ipc_rfs_client_recv(struct ipc_client *client, struct ipc_message_inf return 0; } -int crespo_ipc_open(void *data, unsigned int size, void *io_data) +int crespo_ipc_open(int type, void *io_data) { - int type = *((int *) data); int fd = -1; switch(type) @@ -453,7 +480,7 @@ int crespo_ipc_open(void *data, unsigned int size, void *io_data) return 0; } -int crespo_ipc_close(void *data, unsigned int size, void *io_data) +int crespo_ipc_close(void *io_data) { int fd = -1; @@ -559,9 +586,9 @@ int crespo_ipc_power_off(void *io_data) return 0; } -int crespo_ipc_gprs_get_iface(char **iface) +int crespo_ipc_gprs_get_iface(char **iface, int cid) { - asprintf(iface, GPRS_IFACE); + asprintf(iface, "%s%d", GPRS_IFACE_PREFIX, 0); return 0; } diff --git a/samsung-ipc/device/crespo/crespo_ipc.h b/samsung-ipc/device/crespo/crespo_ipc.h index fc06826..47c8da8 100644 --- a/samsung-ipc/device/crespo/crespo_ipc.h +++ b/samsung-ipc/device/crespo/crespo_ipc.h @@ -28,7 +28,7 @@ #define MAX_MODEM_DATA_SIZE 0x50000 -#define GPRS_IFACE "rmnet0" +#define GPRS_IFACE_PREFIX "rmnet" extern struct ipc_handlers crespo_ipc_default_handlers; diff --git a/samsung-ipc/device/galaxys2/galaxys2_loader.c b/samsung-ipc/device/galaxys2/galaxys2_loader.c index cb44e0a..4647cac 100644 --- a/samsung-ipc/device/galaxys2/galaxys2_loader.c +++ b/samsung-ipc/device/galaxys2/galaxys2_loader.c @@ -435,10 +435,13 @@ static int galaxys2_send_secure_images(struct ipc_client *client, ipc_client_log(client, "sent FIRMWARE image"); } - nv_data_check(client); - nv_data_md5_check(client); + if (nv_data_check(client) < 0) + goto fail; + + if (nv_data_md5_check(client) < 0) + goto fail; - nv_data = ipc_file_read(client, nv_data_path(client), 2 << 20, 1024); + nv_data = ipc_client_file_read(client, nv_data_path(client), 2 << 20, 1024); if (nv_data == NULL) { ipc_client_log(client, "Error: failed to read NVDATA image"); goto fail; diff --git a/samsung-ipc/device/h1/h1_ipc.c b/samsung-ipc/device/h1/h1_ipc.c index 8e20dd2..ca7fd6a 100644 --- a/samsung-ipc/device/h1/h1_ipc.c +++ b/samsung-ipc/device/h1/h1_ipc.c @@ -129,7 +129,7 @@ int h1_ipc_send(struct ipc_client *client, struct ipc_message_info *request) ipc_command_to_str(IPC_COMMAND(request)), ipc_response_type_to_str(request->type)); - ipc_hex_dump(client, frame, frame_length); + ipc_client_hex_dump(client, frame, frame_length); client->handlers->write(frame, frame_length, client->handlers->write_data); @@ -172,7 +172,7 @@ int h1_ipc_recv(struct ipc_client *client, struct ipc_message_info *response) ipc_command_to_str(IPC_COMMAND(response)), ipc_response_type_to_str(response->type)); - ipc_hex_dump(client, data, num_read-1); + ipc_client_hex_dump(client, data, num_read-1); return 0; } diff --git a/samsung-ipc/device/maguro/maguro_loader.c b/samsung-ipc/device/maguro/maguro_loader.c index 1eb7fff..0ee71a0 100644 --- a/samsung-ipc/device/maguro/maguro_loader.c +++ b/samsung-ipc/device/maguro/maguro_loader.c @@ -481,9 +481,14 @@ static int maguro_send_mps_data(struct ipc_client *client, mps_fd = open(I9250_MPS_IMAGE_PATH, O_RDONLY); if (mps_fd < 0) { ipc_client_log(client, "Error: failed to open MPS data"); + goto fail; } else { - read(mps_fd, mps_data, I9250_MPS_LENGTH); + ret = read(mps_fd, mps_data, I9250_MPS_LENGTH); + if (ret < 0) { + ipc_client_log(client, "Error: failed to read MPS data\n"); + goto fail; + } } if ((ret = maguro_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { @@ -535,10 +540,13 @@ static int maguro_send_image_addrs(struct ipc_client *client, ipc_client_log(client, "sent FIRMWARE image"); } - nv_data_check(client); - nv_data_md5_check(client); + if (nv_data_check(client) < 0) + goto fail; + + if (nv_data_md5_check(client) < 0) + goto fail; - nv_data = ipc_file_read(client, nv_data_path(client), 2 << 20, 1024); + nv_data = ipc_client_file_read(client, nv_data_path(client), 2 << 20, 1024); if (nv_data == NULL) { ipc_client_log(client, "Error: failed to read NVDATA image"); goto fail; diff --git a/samsung-ipc/device/xmm6260/xmm6260_ipc.c b/samsung-ipc/device/xmm6260/xmm6260_ipc.c index 7544fd3..205c73b 100644 --- a/samsung-ipc/device/xmm6260/xmm6260_ipc.c +++ b/samsung-ipc/device/xmm6260/xmm6260_ipc.c @@ -242,9 +242,8 @@ int xmm6260_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_in return rc; } -int xmm6260_ipc_open(void *data, unsigned int size, void *io_data) +int xmm6260_ipc_open(int type, void *io_data) { - int type = *((int *) data); int fd = -1; switch(type) @@ -270,7 +269,7 @@ int xmm6260_ipc_open(void *data, unsigned int size, void *io_data) return 0; } -int xmm6260_ipc_close(void *data, unsigned int size, void *io_data) +int xmm6260_ipc_close(void *io_data) { int fd = -1; @@ -345,10 +344,14 @@ int xmm6260_ipc_power_off(void *io_data) return 0; } -int xmm6260_ipc_gprs_get_iface(char **iface) +int xmm6260_ipc_gprs_get_iface(char **iface, int cid) { - // TODO: depends on CID - asprintf(iface, GPRS_IFACE); + if(cid > GPRS_IFACE_COUNT) { + *iface = NULL; + return -1; + } + + asprintf(iface, "%s%d", GPRS_IFACE_PREFIX, cid - 1); return 0; } @@ -359,7 +362,7 @@ int xmm6260_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *cap) return -1; cap->port_list = 1; - cap->cid_max = 3; + cap->cid_max = GPRS_IFACE_COUNT; return 0; } diff --git a/samsung-ipc/device/xmm6260/xmm6260_ipc.h b/samsung-ipc/device/xmm6260/xmm6260_ipc.h index 14a0cfb..58bd8a2 100644 --- a/samsung-ipc/device/xmm6260/xmm6260_ipc.h +++ b/samsung-ipc/device/xmm6260/xmm6260_ipc.h @@ -26,8 +26,9 @@ #ifndef __XMM6260_IPC_H__ #define __XMM6260_IPC_H__ -#define IPC_MAX_XFER 4096 -#define GPRS_IFACE "rmnet0" +#define IPC_MAX_XFER 4096 +#define GPRS_IFACE_PREFIX "rmnet" +#define GPRS_IFACE_COUNT 3 struct rfs_hdr { uint32_t size; @@ -39,13 +40,13 @@ int xmm6260_ipc_fmt_client_send(struct ipc_client *client, struct ipc_message_in int xmm6260_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response); int xmm6260_ipc_rfs_client_recv(struct ipc_client *client, struct ipc_message_info *response); int xmm6260_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_info *request); -int xmm6260_ipc_open(void *data, unsigned int size, void *io_data); -int xmm6260_ipc_close(void *data, unsigned int size, void *io_data); +int xmm6260_ipc_open(int type, void *io_data); +int xmm6260_ipc_close(void *io_data); int xmm6260_ipc_read(void *data, unsigned int size, void *io_data); int xmm6260_ipc_write(void *data, unsigned int size, void *io_data); int xmm6260_ipc_power_on(void *io_data); int xmm6260_ipc_power_off(void *io_data); -int xmm6260_ipc_gprs_get_iface(char **iface); +int xmm6260_ipc_gprs_get_iface(char **iface, int cid); int xmm6260_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *cap); void *xmm6260_ipc_common_data_create(void); int xmm6260_ipc_common_data_destroy(void *io_data); diff --git a/samsung-ipc/gprs.c b/samsung-ipc/gprs.c index c9edf7b..42dcd59 100644 --- a/samsung-ipc/gprs.c +++ b/samsung-ipc/gprs.c @@ -30,36 +30,44 @@ void ipc_gprs_port_list_setup(struct ipc_gprs_port_list *message) 0x02, 0x04, 0x16, 0x00, 0x17, 0x00, 0x87, 0x00, 0xBD, 0x01 }; - memset(message->unk, 0, sizeof(message->unk)); - memcpy(message->unk, bytes, sizeof(bytes)); + assert(message != NULL); + + memset(message, 0, sizeof(struct ipc_gprs_port_list)); + memcpy(message->unk, bytes, sizeof(bytes)); } -void ipc_gprs_define_pdp_context_setup(struct ipc_gprs_define_pdp_context *message, char *apn) +void ipc_gprs_define_pdp_context_setup(struct ipc_gprs_define_pdp_context *message, + unsigned char cid, int enable, char *apn) { assert(message != NULL); - message->unk0[0] = 0x1; - message->unk0[1] = 0x1; - message->unk0[2] = 0x2; - strncpy((char*)message->apn, apn, 124); + + memset(message, 0, sizeof(struct ipc_gprs_define_pdp_context)); + + message->enable = enable ? 1 : 0; + message->cid = cid; + message->unk = 0x2; + + strncpy((char *) message->apn, apn, 124); } -void ipc_gprs_pdp_context_setup(struct ipc_gprs_pdp_context *message, int activate, char *username, char *password) +void ipc_gprs_pdp_context_setup(struct ipc_gprs_pdp_context_set *message, + unsigned char cid, int enable, char *username, char *password) { assert(message != NULL); - if (activate) + + memset(message, 0, sizeof(struct ipc_gprs_pdp_context_set)); + + message->enable = enable ? 1 : 0; + message->cid = cid; + + if (enable && username != NULL && password != NULL) { - message->unk0[0] = 0x1; - message->unk0[1] = 0x1; message->unk0[2] = 0x13; message->unk2 = 0x1; strncpy((char*)message->username, username, 32); strncpy((char*)message->password, password, 32); } - else - { - message->unk0[1] = 0x1; - } } // vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index a2662d1..8cd2488 100644 --- a/samsung-ipc/ipc.c +++ b/samsung-ipc/ipc.c @@ -333,7 +333,7 @@ int ipc_client_open(struct ipc_client *client) type = client->type; - return client->handlers->open(&type, 0, client->handlers->open_data); + return client->handlers->open(type, client->handlers->open_data); } int ipc_client_close(struct ipc_client *client) @@ -343,7 +343,7 @@ int ipc_client_close(struct ipc_client *client) client->handlers->close == NULL) return -1; - return client->handlers->close(NULL, 0, client->handlers->close_data); + return client->handlers->close(client->handlers->close_data); } int ipc_client_power_on(struct ipc_client *client) @@ -399,14 +399,14 @@ int ipc_client_gprs_deactivate(struct ipc_client *client) return client->handlers->gprs_deactivate(client->handlers->gprs_deactivate_data); } -int ipc_client_gprs_get_iface(struct ipc_client *client, char **iface) +int ipc_client_gprs_get_iface(struct ipc_client *client, char **iface, int cid) { if (client == NULL || client->gprs_specs == NULL || client->gprs_specs->gprs_get_iface == NULL) return -1; - return client->gprs_specs->gprs_get_iface(iface); + return client->gprs_specs->gprs_get_iface(iface, cid); } int ipc_client_gprs_get_capabilities(struct ipc_client *client, struct ipc_client_gprs_capabilities *cap) diff --git a/samsung-ipc/ipc_private.h b/samsung-ipc/ipc_private.h index 6db8df3..6c7e0ad 100644 --- a/samsung-ipc/ipc_private.h +++ b/samsung-ipc/ipc_private.h @@ -35,9 +35,10 @@ struct ipc_handlers { void *read_data; ipc_io_handler_cb write; void *write_data; - ipc_io_handler_cb open; + + int (*open)(int type, void *io_data); + int (*close)(void *io_data); void *open_data; - ipc_io_handler_cb close; void *close_data; /* Power handlers */ @@ -62,7 +63,7 @@ struct ipc_handlers { }; struct ipc_gprs_specs { - int (*gprs_get_iface)(char **iface); + int (*gprs_get_iface)(char **iface, int cid); int (*gprs_get_capabilities)(struct ipc_client_gprs_capabilities *cap); }; diff --git a/samsung-ipc/ipc_util.c b/samsung-ipc/ipc_util.c index 500f4a1..7f6973e 100644 --- a/samsung-ipc/ipc_util.c +++ b/samsung-ipc/ipc_util.c @@ -35,7 +35,7 @@ #define IPC_STR(f) case f: return strdup(#f); void ipc_client_log_recv(struct ipc_client *client, - struct ipc_message_info *response, char *prefix) + struct ipc_message_info *response, const char *prefix) { switch (client->type) { case IPC_CLIENT_TYPE_FMT: @@ -45,7 +45,7 @@ void ipc_client_log_recv(struct ipc_client *client, #ifdef DEBUG if (response->length > 0) { ipc_client_log(client, "==== FMT DATA DUMP ===="); - ipc_hex_dump(client, (void *) response->data, + ipc_client_hex_dump(client, (void *) response->data, response->length > 0x100 ? 0x100 : response->length); } #endif @@ -57,7 +57,7 @@ void ipc_client_log_recv(struct ipc_client *client, #ifdef DEBUG if (response->length > 0) { ipc_client_log(client, "==== RFS DATA DUMP ===="); - ipc_hex_dump(client, (void *) response->data, + ipc_client_hex_dump(client, (void *) response->data, response->length > 0x100 ? 0x100 : response->length); } #endif @@ -68,7 +68,7 @@ void ipc_client_log_recv(struct ipc_client *client, } void ipc_client_log_send(struct ipc_client *client, - struct ipc_message_info *request, char *prefix) + struct ipc_message_info *request, const char *prefix) { switch (client->type) { case IPC_CLIENT_TYPE_FMT: @@ -78,7 +78,7 @@ void ipc_client_log_send(struct ipc_client *client, #ifdef DEBUG if (request->length > 0) { ipc_client_log(client, "==== FMT DATA DUMP ===="); - ipc_hex_dump(client, (void *) request->data, + ipc_client_hex_dump(client, (void *) request->data, request->length > 0x100 ? 0x100 : request->length); } #endif @@ -90,7 +90,7 @@ void ipc_client_log_send(struct ipc_client *client, #ifdef DEBUG if (request->length > 0) { ipc_client_log(client, "==== RFS DATA DUMP ===="); - ipc_hex_dump(client, (void *) request->data, + ipc_client_hex_dump(client, (void *) request->data, request->length > 0x100 ? 0x100 : request->length); } #endif @@ -253,7 +253,7 @@ const char *ipc_command_to_str(int command) { } } -void ipc_hex_dump(struct ipc_client *client, void *data, int size) +void ipc_client_hex_dump(struct ipc_client *client, void *data, int size) { /* dumps size bytes of *data to stdout. Looks like: * [0000] 75 6E 6B 6E 6F 77 6E 20 @@ -271,8 +271,10 @@ void ipc_hex_dump(struct ipc_client *client, void *data, int size) for (n=1;n<=size;n++) { if (n%16 == 1) { /* store address for this line */ - snprintf(addrstr, sizeof(addrstr), "%.4x", - ((unsigned int)p-(unsigned int)data) ); + unsigned int end = 0, start = 0; + end = *((unsigned int*) p); + start = *((unsigned int*) data); + snprintf(addrstr, sizeof(addrstr), "%.4x", end - start); } c = *p; @@ -307,7 +309,7 @@ void ipc_hex_dump(struct ipc_client *client, void *data, int size) } } -void *ipc_mtd_read(struct ipc_client *client, char *mtd_name, int size, int block_size) +void *ipc_client_mtd_read(struct ipc_client *client, char *mtd_name, int size, int block_size) { void *mtd_p=NULL; uint8_t *data_p=NULL; @@ -319,7 +321,7 @@ void *ipc_mtd_read(struct ipc_client *client, char *mtd_name, int size, int bloc if (mtd_name == NULL || size <= 0 || block_size <= 0) goto error; - ipc_client_log(client, "ipc_mtd_read: reading 0x%x bytes from %s with 0x%x bytes block size\n", size, mtd_name, block_size); + ipc_client_log(client, "ipc_client_mtd_read: reading 0x%x bytes from %s with 0x%x bytes block size\n", size, mtd_name, block_size); fd=open(mtd_name, O_RDONLY); if (fd < 0) @@ -338,7 +340,7 @@ void *ipc_mtd_read(struct ipc_client *client, char *mtd_name, int size, int bloc offs = i * block_size; if (ioctl(fd, MEMGETBADBLOCK, &offs) == 1) { - ipc_client_log(client, "ipc_mtd_read: warning: bad block at offset %lld\n", (long long int) offs); + ipc_client_log(client, "ipc_client_mtd_read: warning: bad block at offset %lld\n", (long long int) offs); data_p+=block_size; continue; } @@ -352,11 +354,11 @@ void *ipc_mtd_read(struct ipc_client *client, char *mtd_name, int size, int bloc return mtd_p; error: - ipc_client_log(client, "ipc_mtd_read: something went wrong\n"); + ipc_client_log(client, "ipc_client_mtd_read: something went wrong\n"); return NULL; } -void *ipc_file_read(struct ipc_client *client, char *file_name, int size, int block_size) +void *ipc_client_file_read(struct ipc_client *client, char *file_name, int size, int block_size) { void *file_p=NULL; uint8_t *data_p=NULL; @@ -367,7 +369,7 @@ void *ipc_file_read(struct ipc_client *client, char *file_name, int size, int bl if (file_name == NULL || size <= 0 || block_size <= 0) goto error; - ipc_client_log(client, "ipc_file_read: reading 0x%x bytes from %s with 0x%x bytes block size\n", size, file_name, block_size); + ipc_client_log(client, "ipc_client_file_read: reading 0x%x bytes from %s with 0x%x bytes block size\n", size, file_name, block_size); fd=open(file_name, O_RDONLY); if (fd < 0) @@ -392,7 +394,7 @@ void *ipc_file_read(struct ipc_client *client, char *file_name, int size, int bl return file_p; error: - ipc_client_log(client, "ipc_file_read: something went wrong\n"); + ipc_client_log(client, "ipc_client_file_read: something went wrong\n"); return NULL; } diff --git a/samsung-ipc/rfs.c b/samsung-ipc/rfs.c index 4d2fb19..c6e58f8 100644 --- a/samsung-ipc/rfs.c +++ b/samsung-ipc/rfs.c @@ -151,14 +151,15 @@ void nv_data_md5_compute(void *data_p, int size, char *secret, void *hash) void nv_data_md5_generate(struct ipc_client *client) { uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH]; - char *nv_data_md5_hash_string; - void *nv_data_p; + char *nv_data_md5_hash_string = NULL; + void *nv_data_p = NULL; int fd; + int rc; ipc_client_log(client, "nv_data_md5_generate: enter\n"); ipc_client_log(client, "nv_data_md5_generate: generating MD5 hash\n"); - nv_data_p=ipc_file_read(client, nv_data_path(client), + nv_data_p=ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client)); nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash); free(nv_data_p); @@ -172,20 +173,28 @@ void nv_data_md5_generate(struct ipc_client *client) ipc_client_log(client, "nv_data_md5_generate: new MD5 hash is %s\n", nv_data_md5_hash_string); ipc_client_log(client, "nv_data_md5_generate: writing MD5 hash\n"); + /* Write the MD5 hash in nv_data.bin.md5. */ fd = open(nv_data_md5_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644); - if (fd < 0) { ipc_client_log(client, "nv_data_md5_generate: fd open failed\n"); goto exit; } - write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE); + rc = write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_md5_generate: failed to write MD5 hash to file\n"); + close(fd); + goto exit; + } + close(fd); exit: - free(nv_data_md5_hash_string); + if (nv_data_md5_hash_string != NULL) + free(nv_data_md5_hash_string); ipc_client_log(client, "nv_data_md5_generate: exit\n"); } @@ -193,13 +202,13 @@ exit: void nv_data_backup_create(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; + char *nv_data_md5_hash_string = NULL; + char *nv_data_md5_hash_read = NULL; int nv_data_write_tries = 0; struct stat nv_stat; - void *nv_data_p; - void *nv_data_bak_p; + void *nv_data_p = NULL; + void *nv_data_bak_p = NULL; uint8_t data; int fd; @@ -236,7 +245,7 @@ void nv_data_backup_create(struct ipc_client *client) memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE); /* Read the content of the backup file. */ - nv_data_p=ipc_file_read(client, nv_data_path(client), + nv_data_p=ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client)); /* Compute the backup file MD5 hash. */ @@ -244,8 +253,21 @@ void nv_data_backup_create(struct ipc_client *client) md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash); /* Read the stored backup file MD5 hash. */ - fd=open(nv_data_md5_path(client), O_RDONLY); - read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + fd = open(nv_data_md5_path(client), O_RDONLY); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to openstored backup file with MD5 hash\n"); + goto exit; + } + + rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to read MD5 hash from backup file\n"); + close(fd); + goto exit; + } + close(fd); /* Add 0x0 to end the string: not sure this is always part of the file. */ @@ -259,8 +281,20 @@ void nv_data_backup_create(struct ipc_client *client) ipc_client_log(client, "nv_data_backup_create: MD5 hash mismatch on backup file\n"); ipc_client_log(client, "nv_data_backup_create: Consider the computed one as correct\n"); - fd=open(nv_data_md5_path(client), O_WRONLY); - read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE); + fd = open(nv_data_md5_path(client), O_WRONLY); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to open file with MD5 hash of data file\n"); + goto exit; + } + + rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to read MD5 hash for data file from file\n"); + goto exit; + } + close(fd); /* @@ -279,7 +313,7 @@ nv_data_backup_create_write: { ipc_client_log(client, "nv_data_backup_create: .nv_data.bak write try #%d\n", nv_data_write_tries + 1); - fd=open(nv_data_bak_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644); + fd = open(nv_data_bak_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd < 0) { ipc_client_log(client, "nv_data_backup_create: negative fd while opening /efs/.nv_data.bak, error: %s\n", strerror(errno)); @@ -308,14 +342,15 @@ nv_data_backup_create_write: } /* Read the newly-written .nv_data.bak. */ - nv_data_bak_p=ipc_file_read(client, nv_data_bak_path(client), + nv_data_bak_p = ipc_client_file_read(client, nv_data_bak_path(client), nv_data_size(client), nv_data_chunk_size(client)); /* Compute the MD5 hash for nv_data.bin. */ nv_data_md5_compute(nv_data_bak_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash); md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash); - free(nv_data_bak_p); + if (nv_data_bak_p != NULL) + free(nv_data_bak_p); ipc_client_log(client, "nv_data_backup_create: written file computed MD5: %s read MD5: %s\n", nv_data_md5_hash_string, nv_data_md5_hash_read); @@ -330,20 +365,48 @@ nv_data_backup_create_write: } /* Write the MD5 hash in .nv_data.bak.md5. */ - fd=open(nv_data_md5_bak_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); - write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + fd = open(nv_data_md5_bak_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to open MD5 hash file\n"); + goto exit; + } + + rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to write MD5 hash to file\n"); + close(fd); + goto exit; + } close(fd); /* Write the correct .nv_state. */ - fd=open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); + fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to open NV state file\n"); + goto exit; + } + data='1'; - write(fd, &data, sizeof(data)); + rc = write(fd, &data, sizeof(data)); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_create: failed to write state of NV data\n"); + close(fd); + goto exit; + } + close(fd); exit: - free(nv_data_p); - free(nv_data_md5_hash_string); - free(nv_data_md5_hash_read); + if (nv_data_p != NULL) + free(nv_data_p); + if (nv_data_md5_hash_string != NULL) + free(nv_data_md5_hash_string); + if (nv_data_md5_hash_read) + free(nv_data_md5_hash_read); ipc_client_log(client, "nv_data_backup_create: exit\n"); } @@ -351,13 +414,13 @@ exit: 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; + char *nv_data_md5_hash_string = NULL; + char *nv_data_md5_hash_read = NULL; int nv_data_write_tries = 0; struct stat nv_stat; - void *nv_data_p; - void *nv_data_bak_p; + void *nv_data_p = NULL; + void *nv_data_bak_p = NULL; uint8_t data; int fd; @@ -398,7 +461,7 @@ void nv_data_backup_restore(struct ipc_client *client) memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE); /* Read the content of the backup file. */ - nv_data_bak_p=ipc_file_read(client, nv_data_bak_path(client), + nv_data_bak_p=ipc_client_file_read(client, nv_data_bak_path(client), nv_data_size(client), nv_data_chunk_size(client)); /* Compute the backup file MD5 hash. */ @@ -407,7 +470,14 @@ void nv_data_backup_restore(struct ipc_client *client) /* Read the stored backup file MD5 hash. */ fd=open(nv_data_md5_bak_path(client), O_RDONLY); - read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_restore: Failed to read md5 hash for stored back file\n"); + close(fd); + goto exit; + } + close(fd); /* Add 0x0 to end the string: not sure this is always part of the file. */ @@ -421,8 +491,21 @@ void nv_data_backup_restore(struct ipc_client *client) ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on backup file\n"); ipc_client_log(client, "nv_data_backup_restore: Consider the computed one as correct\n"); - fd=open(nv_data_md5_bak_path(client), O_WRONLY); - read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE); + fd = open(nv_data_md5_bak_path(client), O_WRONLY); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_restore: failed to open MD5 hash backup file\n"); + goto exit; + } + + rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_restore: failed to read MD5 hash from backup file\n"); + close(fd); + goto exit; + } + close(fd); /* @@ -467,18 +550,21 @@ nv_data_backup_restore_write: ipc_client_log(client, "nv_data_backup_restore: writing the backup to nv_data.bin failed too many times\n"); unlink(nv_data_path(client)); goto exit; - } /* Read the newly-written nv_data.bin. */ - nv_data_p=ipc_file_read(client, nv_data_path(client), + nv_data_p=ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client)); /* Compute the MD5 hash for nv_data.bin. */ nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash); md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash); - free(nv_data_p); + if (nv_data_p != NULL) + { + free(nv_data_p); + nv_data_p = NULL; + } ipc_client_log(client, "nv_data_backup_restore: written file computed MD5: %s read MD5: %s\n", nv_data_md5_hash_string, nv_data_md5_hash_read); @@ -493,29 +579,58 @@ nv_data_backup_restore_write: } /* Write the MD5 hash in nv_data.bin.md5. */ - fd=open(nv_data_md5_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); - write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + fd = open(nv_data_md5_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_restore: failed to open file with MD5 hash\n"); + goto exit; + } + + rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_restore: failed to write MD5 hash to file\n"); + close(fd); + goto exit; + } close(fd); /* Write the correct .nv_state. */ - fd=open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); + fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + { + ipc_client_log(client, "nv_data_backup_restore: failed to open NV state file\n"); + goto exit; + } + data='1'; - write(fd, &data, sizeof(data)); + rc = write(fd, &data, sizeof(data)); + if (rc < 0) + { + ipc_client_log(client, "nv_data_backup_restore: failed to write state to file\n"); + close(fd); + goto exit; + } + close(fd); exit: - free(nv_data_bak_p); - free(nv_data_md5_hash_string); - free(nv_data_md5_hash_read); + if (nv_data_bak_p != NULL) + free(nv_data_bak_p); + if (nv_data_md5_hash_string != NULL) + free(nv_data_md5_hash_string); + if (nv_data_md5_hash_read != NULL) + free(nv_data_md5_hash_read); ipc_client_log(client, "nv_data_backup_restore: exit\n"); } -void nv_data_check(struct ipc_client *client) +int nv_data_check(struct ipc_client *client) { struct stat nv_stat; int nv_state_fd=-1; int nv_state=0; + int rc; ipc_client_log(client, "nv_data_check: enter\n"); @@ -542,7 +657,7 @@ void nv_data_check(struct ipc_client *client) { ipc_client_log(client, "nv_data_check: .nv_data.bak or .nv_data.bak.md5 missing\n"); nv_data_backup_create(client); - } + } nv_state_fd=open(nv_state_path(client), O_RDONLY); @@ -552,7 +667,12 @@ void nv_data_check(struct ipc_client *client) nv_data_backup_restore(client); } - read(nv_state_fd, &nv_state, sizeof(nv_state)); + rc = read(nv_state_fd, &nv_state, sizeof(nv_state)); + if (rc < 0) + { + ipc_client_log(client, "nv_data_check: couldn't read state of NV item from file\n"); + return -1; + } close(nv_state_fd); @@ -564,17 +684,19 @@ void nv_data_check(struct ipc_client *client) ipc_client_log(client, "nv_data_check: everything should be alright\n"); ipc_client_log(client, "nv_data_check: exit\n"); + + return 0; } -void nv_data_md5_check(struct ipc_client *client) +int 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; - + char *nv_data_md5_hash_string = NULL; + char *nv_data_md5_hash_read = NULL; + void *nv_data_p = NULL; int fd; + int rc; uint8_t *data_p; ipc_client_log(client, "nv_data_md5_check: enter\n"); @@ -585,7 +707,7 @@ void nv_data_md5_check(struct ipc_client *client) 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, nv_data_path(client), + nv_data_p=ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client)); data_p=nv_data_p; @@ -598,7 +720,12 @@ void nv_data_md5_check(struct ipc_client *client) fd=open(nv_data_md5_path(client), O_RDONLY); /* Read the md5 stored in the file. */ - read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE); + if (rc < 0) + { + ipc_client_log(client, "nv_data_md5_check: Can't read md5 hash from file\n"); + return -1; + } /* Add 0x0 to end the string: not sure this is part of the file. */ nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0'; @@ -612,10 +739,14 @@ void nv_data_md5_check(struct ipc_client *client) nv_data_backup_restore(client); } - free(nv_data_md5_hash_string); - free(nv_data_md5_hash_read); + if (nv_data_md5_hash_string != NULL) + free(nv_data_md5_hash_string); + if (nv_data_md5_hash_read != NULL) + free(nv_data_md5_hash_read); ipc_client_log(client, "nv_data_md5_check: exit\n"); + + return 0; } int nv_data_read(struct ipc_client *client, int offset, int length, char *buf) @@ -635,7 +766,8 @@ int nv_data_read(struct ipc_client *client, int offset, int length, char *buf) return -1; } - nv_data_check(client); + if (nv_data_check(client) < 0) + return -1; fd = open(nv_data_path(client), O_RDONLY); @@ -675,7 +807,8 @@ int nv_data_write(struct ipc_client *client, int offset, int length, char *buf) return -1; } - nv_data_check(client); + if (nv_data_check(client) < 0) + return -1; fd = open(nv_data_path(client), O_WRONLY); @@ -726,7 +859,7 @@ void ipc_rfs_send_io_confirm_for_nv_read_item(struct ipc_client *client, struct #ifdef DEBUG ipc_client_log(client, "Read rfs_data dump:"); - ipc_hex_dump(client, rfs_data, rfs_io->length); + ipc_client_hex_dump(client, rfs_data, rfs_io->length); #endif ipc_client_log(client, "Preparing RFS IO Confirm message (rc is %d)", rc); @@ -734,7 +867,8 @@ void ipc_rfs_send_io_confirm_for_nv_read_item(struct ipc_client *client, struct rfs_io_conf->offset = rfs_io->offset; rfs_io_conf->length = rfs_io->length; - ipc_client_send(client, IPC_RFS_NV_READ_ITEM, 0, rfs_io_conf, rfs_io->length + sizeof(struct ipc_rfs_io_confirm), info->aseq); + ipc_client_send(client, IPC_RFS_NV_READ_ITEM, 0, (unsigned char*) rfs_io_conf, + rfs_io->length + sizeof(struct ipc_rfs_io_confirm), info->aseq); free(rfs_io_conf); } @@ -755,7 +889,7 @@ void ipc_rfs_send_io_confirm_for_nv_write_item(struct ipc_client *client, struct #ifdef DEBUG ipc_client_log(client, "Write rfs_data dump:"); - ipc_hex_dump(client, rfs_data, rfs_io->length); + ipc_client_hex_dump(client, rfs_data, rfs_io->length); #endif ipc_client_log(client, "Asked to write 0x%x bytes at offset 0x%x", rfs_io->length, rfs_io->offset); @@ -767,7 +901,8 @@ void ipc_rfs_send_io_confirm_for_nv_write_item(struct ipc_client *client, struct rfs_io_conf->offset = rfs_io->offset; rfs_io_conf->length = rfs_io->length; - ipc_client_send(client, IPC_RFS_NV_WRITE_ITEM, 0, rfs_io_conf, sizeof(struct ipc_rfs_io_confirm), info->aseq); + ipc_client_send(client, IPC_RFS_NV_WRITE_ITEM, 0, (unsigned char*) rfs_io_conf, + sizeof(struct ipc_rfs_io_confirm), info->aseq); free(rfs_io_conf); } diff --git a/vapi/samsung-ipc-1.0.vapi b/vapi/samsung-ipc-1.0.vapi index 6696409..1757512 100644 --- a/vapi/samsung-ipc-1.0.vapi +++ b/vapi/samsung-ipc-1.0.vapi @@ -115,6 +115,7 @@ namespace SamsungIpc GPRS_DATA_DORMANT, GPRS_DUN_PIN_CTRL, GPRS_CALL_STATUS, + GPRS_PORT_LIST, SAT_PROFILE_DOWNLOAD, SAT_ENVELOPE_CMD, SAT_PROACTIVE_CMD, @@ -941,27 +942,42 @@ namespace SamsungIpc namespace Gprs { - [CCode (cname = "gint8", cprefix = "IPC_GPRS_CALL_STATUS_TYPE_", has_type_id = false)] - public enum CallStatusType + [CCode (cname = "IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT")] + public uint MAX_PDP_CONTEXT_COUNT; + + [CCode (cname = "gint8", cprefix = "IPC_GPRS_STATE_", has_type_id = false)] + public enum State { - ON, - OFF, + NOT_ENABLED, + ENABLED, + DISABLED } - [CCode (cname = "gint8", cprefix = "IPC_GPRS_ERROR_", has_type_id = false)] - public enum ErrorType + [CCode (cname = "gint8", cprefix = "IPC_GPRS_FAIL_", has_type_id = false)] + public enum Error { - UNAVAILABLE, + INSUFFICIENT_RESOURCES, + MISSING_UNKNOWN_APN, + UNKNOWN_PDP_ADDRESS_TYPE, + USER_AUTHENTICATION, + ACTIVATION_REJECT_CGSN, + ACTIVATION_REJECT_UNSPECIFIED, + SERVICE_OPTION_NOT_SUPPORTED, + SERVICE_OPTION_NOT_SUBSCRIBED, + SERVICE_OPTION_OUT_OF_ORDER, + NSAPI_IN_USE } [CCode (cname = "struct ipc_gprs_define_pdp_context", destroy_function = "")] public struct DefinePdpContextMessage { - public uint8[] unk0; + public uint8 enable; + public uint8 cid; + public uint8 unk; public uint8[] apn; [CCode (cname = "ipc_gprs_define_pdp_context_setup")] - public void setup(string apn); + public void setup(uint8 cid, bool enable, string apn); public unowned uint8[] data { @@ -977,7 +993,7 @@ namespace SamsungIpc [CCode (cname = "struct ipc_gprs_ip_configuration", destroy_function = "")] public struct IpConfigurationMessage { - public uint8 unk0; + public uint8 cid; public uint8 field_flag; public uint8 unk1; [CCode (array_length = false)] @@ -1004,12 +1020,47 @@ namespace SamsungIpc } } + [CCode (name = "struct ipc_gprs_pdp_context_get_desc", destroy_function = "")] + public struct PdpContextGetDescMessage + { + public uint8 cid; + public uint8 state; + + public unowned uint8[] data + { + get + { + unowned uint8[] res = (uint8[])(&this); + res.length = (int) sizeof( PdpContextGetDescMessage ); + return res; + } + } + } + + [CCode (name = "struct ipc_gprs_pdp_context_get", destroy_function = "")] + public struct PdpContextGetMessage + { + public uint8 unk; + public PdpContextGetDescMessage[] desc; + + public unowned uint8[] data + { + get + { + unowned uint8[] res = (uint8[])(&this); + res.length = (int) sizeof( PdpContextGetMessage ); + return res; + } + } + } + + [CCode (name = "struct ipc_gprs_call_status", destroy_function = "")] public struct CallStatusMessage { public uint8 cid; - public CallStatusType status; - public uint16 reason; + public State status; + public uint16 fail_status; public unowned uint8[] data { @@ -1038,23 +1089,26 @@ namespace SamsungIpc } } - [CCode (cname = "struct ipc_gprs_pdp_context", destroy_function = "")] - public struct PdpContextMessage + [CCode (cname = "struct ipc_gprs_pdp_context_set", destroy_function = "")] + public struct PdpContextSetMessage { + public uint8 enable; + public uint8 cid; public uint8[] unk0; public uint8[] username; public uint8[] password; public uint8[] unk1; + public uint8 unk2; [CCode (cname = "ipc_gprs_pdp_context_setup")] - public void setup(bool activate, string? username, string? password); + public void setup(int cid, bool activate, string? username, string? password); public unowned uint8[] data { get { unowned uint8[] res = (uint8[])(&this); - res.length = (int) sizeof( PdpContextMessage ); + res.length = (int) sizeof( PdpContextSetMessage ); return res; } } @@ -1079,7 +1133,9 @@ namespace SamsungIpc [CCode (cname = "struct ipc_gprs_current_session_data_counter", destroy_function = "")] public struct CurrentSessionDataCounterMessage { - public uint8[] unk; + public uint8[] cid; + public uint8[] rx_count; + public uint8[] tx_count; public unowned uint8[] data { @@ -1091,6 +1147,25 @@ namespace SamsungIpc } } } + + [CCode (cname = "struct ipc_gprs_port_list")] + public struct PortListMessage + { + public uint8[] unk; + + [CCode (cname = "ipc_gprs_port_list_setup")] + public void setup(); + + public unowned uint8[] data + { + get + { + unowned uint8[] res = (uint8[])(&this); + res.length = (int) sizeof( PortListMessage ); + return res; + } + } + } } /* ******************************************************************************** */ @@ -1295,11 +1370,15 @@ namespace SamsungIpc public int set_log_handler(LogHandlerCb log_cb); public int set_io_handlers(TransportCb write_cb, TransportCb read_cb); public int bootstrap_modem(); - public void open(); - public void close(); + public int open(); + public int close(); + public int power_on(); + public int power_off(); public int recv(out Response response); public void send(MessageType command, RequestType type, uint8[] data, uint8 mseq); public void send_get(MessageType command, uint8 aseq); public void send_exec(MessageType command, uint8 aseq); + public void set_handlers_common_data_fd(int fd); + public int get_handlers_common_data_fd(); } } |