summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-07-18 15:07:43 (GMT)
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-07-18 15:07:43 (GMT)
commit9af74e1e2707bee3dcbf1008682566d330418d8a (patch)
tree4d3740628ba0d88e91f6c5c94abab4cf0d92ef50
parentbcf9438e27b3e678c815b544509706e7b7332451 (diff)
downloadqmi-ril-9af74e1e2707bee3dcbf1008682566d330418d8a.zip
qmi-ril-9af74e1e2707bee3dcbf1008682566d330418d8a.tar.gz
qmi-ril-9af74e1e2707bee3dcbf1008682566d330418d8a.tar.bz2
refactoring and first shot at EFS sync
Receiving the actual EFS data doesn't work yet. And sometimes, the modem ends up in states where it crashes after exchanging hellos. Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
-rw-r--r--Android.mk4
-rw-r--r--boot.c244
-rw-r--r--i9305.h6
-rw-r--r--sahara.c397
-rw-r--r--sahara.h43
5 files changed, 487 insertions, 207 deletions
diff --git a/Android.mk b/Android.mk
index 66cec18..65c1703 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,7 +19,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := boot.c
+LOCAL_SRC_FILES := \
+ boot.c \
+ sahara.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)
diff --git a/boot.c b/boot.c
index 86a189e..d22de18 100644
--- a/boot.c
+++ b/boot.c
@@ -26,187 +26,40 @@
#include <sahara.h>
#include <i9305.h>
-int hello_handshake(int tty_fd)
+int configure_tty(int *tty_fd, time_t timeout_sec, long int timeout_usec)
{
- struct sah_hello_req hello_req;
- struct sah_hello_resp hello_resp;
- int rc;
-
- rc = read(tty_fd, &hello_req, sizeof(hello_req));
- if (rc < (int) sizeof(hello_req)
- || hello_req.header.command != SAH_COMMAND_HELLO_REQ) {
- printf("error receiving hello\n");
- return -1;
- }
-
- if (hello_req.mode != SAH_MODE_TRANSFER_PENDING
- && hello_req.mode != SAH_MODE_TRANSFER_COMPLETE) {
- printf("requested SAHARA mode %d is not supported\n", hello_req.mode);
- return -1;
- }
-
- hello_resp.header.command = SAH_COMMAND_HELLO_RESP;
- hello_resp.header.packet_size = sizeof(hello_resp);
- hello_resp.version = hello_req.version;
- hello_resp.min_version = hello_req.min_version;
- hello_resp.status = 0;
- hello_resp.mode = hello_req.mode;
-
- rc = write(tty_fd, &hello_resp, sizeof(hello_resp));
- if (rc < (int) sizeof(hello_resp)) {
- printf("failed to write hello response\n");
- return -1;
- }
-
- return 0;
-}
-
-int file_for_id(unsigned int id, char **file)
-{
- switch (id) {
- case 6:
- *file = FILE_APPS;
- break;
- case 8:
- *file = FILE_DSP1;
- break;
- case 12:
- *file = FILE_DSP2;
- break;
- case 16:
- *file = FILE_EFS1;
- break;
- case 17:
- *file = FILE_EFS2;
- break;
- case 20:
- *file = FILE_EFS3;
- break;
- case 21:
- *file = FILE_SBL1;
- break;
- case 22:
- *file = FILE_SBL2;
- break;
- case 23:
- *file = FILE_RPM;
- break;
- case 28:
- *file = FILE_DSP3;
- break;
- case 29:
- *file = FILE_ACDB;
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-int send_data(int tty_fd, struct sah_header *header)
-{
- struct sah_data_req data_req;
- char *file = NULL;
- int file_fd;
- char file_data[MAX_DATA_SEND_SIZE];
- int rc;
-
- rc = read(tty_fd, header, sizeof(*header));
- if (rc < (int) sizeof(header)) {
- printf("failed to receive header for data request\n");
- return -1;
- }
-
- if (header->command == SAH_COMMAND_DATA_END_REQ)
- return 1;
-
- rc = read(tty_fd, &data_req, sizeof(data_req));
- if (rc < (int) sizeof(data_req)) {
- printf("error receiving data req\n");
- return -1;
- }
-
- if(data_req.size > MAX_DATA_SEND_SIZE) {
- printf("requested data size is too big\n");
- return -1;
- }
-
- rc = file_for_id(data_req.id, &file);
- if (rc < 0) {
- printf("failed to identify requested file\n");
- return -1;
- }
-
- file_fd = open(file, O_RDONLY);
- if (file_fd < 0) {
- printf("failed to open requested file\n");
- return -1;
- }
-
- lseek(file_fd, data_req.offset, SEEK_SET);
-
- rc = read(file_fd, &file_data, data_req.size);
- if (rc < (int) data_req.size) {
- printf("failed to read data from file\n");
- return -1;
- }
-
- write(tty_fd, &file_data, data_req.size);
- if (rc < (int) data_req.size) {
- printf("failed to send data\n");
- }
-
- return 0;
-}
-
-int send_file(int tty_fd, struct sah_data_end_ack *data_end_ack)
-{
- struct sah_header header;
- struct sah_data_end_req data_end_req;
+ int tty_dev;
+ struct termios termios;
+ struct timeval timeout;
+ fd_set fds;
int rc;
- rc = hello_handshake(tty_fd);
- if (rc < 0) {
- printf("failed to do hello handshake\n");
- return -1;
- }
-
- do {
- rc = send_data(tty_fd, &header);
- if (rc < 0) {
- printf("error while sending data\n");
- return -1;
- }
- } while (header.command == SAH_COMMAND_DATA_REQ);
-
- rc = read(tty_fd, &data_end_req, sizeof(data_end_req));
- if (rc < (int) sizeof(data_end_req)) {
- printf("error receiving data end request\n");
+ tty_dev = open(TTY_DEVICE, O_RDWR | O_SYNC);
+ if (tty_dev < 0) {
+ printf("failed to open modem tty device\n");
return -1;
+ } else {
+ printf("opened modem tty device\n");
}
- if (data_end_req.status != 0) {
- printf("file transfer end status is nonzero\n");
- return -1;
- }
+ tcgetattr(tty_dev, &termios);
+ cfmakeraw(&termios);
+ cfsetispeed(&termios, B9600);
+ cfsetospeed(&termios, B9600);
+ tcsetattr(tty_dev, TCSANOW, &termios);
- printf("id %d: file transfer complete\n", data_end_req.id);
+ FD_ZERO(&fds);
+ FD_SET(tty_dev, &fds);
+ timeout.tv_sec = timeout_sec;
+ timeout.tv_usec = timeout_usec;
- header.command = SAH_COMMAND_DATA_END_RESP;
- header.packet_size = 8;
- rc = write(tty_fd, &header, sizeof(header));
- if (rc < (int) sizeof(header)) {
- printf("failed to write data end response\n");
+ rc = select(tty_dev+1, NULL, &fds, NULL, &timeout);
+ if (rc <= 0) {
+ printf("failed to set timeout\n");
return -1;
}
- rc = read(tty_fd, data_end_ack, sizeof(*data_end_ack));
- if (rc < (int) sizeof(*data_end_ack)
- || data_end_ack->header.command != SAH_COMMAND_DATA_END_ACK) {
- printf("error receiving data end ack\n");
- return -1;
- }
+ *tty_fd = tty_dev;
return 0;
}
@@ -214,12 +67,8 @@ int send_file(int tty_fd, struct sah_data_end_ack *data_end_ack)
int main()
{
int mdm_dev, tty_dev;
- struct termios termios;
- struct timeval timeout;
- fd_set fds;
-
+ int mode;
struct sah_data_end_ack data_end_ack;
-
int rc;
mdm_dev = open(MDM_DEVICE, O_RDONLY | O_NONBLOCK);
@@ -240,29 +89,9 @@ int main()
// wait until modem is awake
sleep(2);
- tty_dev = open(TTY_DEVICE, O_RDWR | O_SYNC);
- if (tty_dev < 0) {
- printf("failed to open modem tty device\n");
- return -1;
- }
- else {
- printf("opened modem tty device\n");
- }
-
- tcgetattr(tty_dev, &termios);
- cfmakeraw(&termios);
- cfsetispeed(&termios, B9600);
- cfsetospeed(&termios, B9600);
- tcsetattr(tty_dev, TCSANOW, &termios);
-
- FD_ZERO(&fds);
- FD_SET(tty_dev, &fds);
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
-
- rc = select(tty_dev + 1, NULL, &fds, NULL, &timeout);
- if (rc <= 0) {
- printf("failed to set timeout\n");
+ rc = configure_tty(&tty_dev, 2, 0);
+ if (rc < 0) {
+ printf("failed to configure serial interface\n");
return -1;
}
@@ -276,6 +105,9 @@ int main()
if(data_end_ack.status == 1) {
printf("all files transferred\n");
+ } else {
+ printf("unknown status for data end ack\n");
+ return -1;
}
close(tty_dev);
@@ -285,7 +117,6 @@ int main()
printf("failed to wait for normal boot\n");
return -1;
}
-
printf("waited for normal boot\n");
rc = ioctl(mdm_dev, WAIT_FOR_ERROR);
@@ -302,5 +133,20 @@ int main()
else
printf("error: cdc-wdm device does not exist\n");
+ printf("\nconfiguring EFS sync\n");
+
+ rc = configure_tty(&tty_dev, 0, 500000);
+ if (rc < 0) {
+ printf("failed to configure serial interface\n");
+ }
+
+ while (1) {
+ rc = handle_memory_debug(tty_dev);
+ if (rc < 0) {
+ printf("error during modem operation\n");
+ return -1;
+ }
+ }
+
return 0;
}
diff --git a/i9305.h b/i9305.h
index e9e6385..e374ef8 100644
--- a/i9305.h
+++ b/i9305.h
@@ -25,6 +25,7 @@
#define WAKE_CHARM _IO(CHARM_CODE, 1)
#define NORMAL_BOOT_DONE _IOW(CHARM_CODE, 5, int)
#define WAIT_FOR_ERROR _IOW(CHARM_CODE, 12, int)
+#define WAIT_FOR_RESTART _IOR(CHARM_CODE, 7, int)
#define MAX_DATA_SEND_SIZE 1*1024*1024
@@ -41,4 +42,9 @@
#define FILE_SBL2 "/firmware/image/sbl2.mbn"
#define FILE_RPM "/firmware/image/rpm.mbn"
+// EFS sync
+#define SYNC_PATH "/dev/block/modem/dump_path/"
+#define SYNC_EFS1 "m9kefs1"
+#define SYNC_EFS2 "m9kefs2"
+
#endif
diff --git a/sahara.c b/sahara.c
new file mode 100644
index 0000000..2533759
--- /dev/null
+++ b/sahara.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2017 Wolfgang Wiedmeyer <wolfgit@wiedmeyer.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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sahara.h>
+#include <i9305.h>
+
+int check_mode(int mode_recv, int mode_expected)
+{
+ if ((mode_expected == SAH_MODE_TRANSFER_PENDING
+ || mode_expected == SAH_MODE_TRANSFER_COMPLETE)
+ && (mode_recv == SAH_MODE_TRANSFER_PENDING
+ || mode_recv == SAH_MODE_TRANSFER_COMPLETE))
+ return 0;
+ else if (mode_recv == mode_expected)
+ return 0;
+ else
+ return -1;
+}
+
+int hello_response(int tty_fd, int mode)
+{
+ struct sah_hello_req hello_req;
+ struct sah_hello_resp hello_resp;
+ int rc;
+
+ rc = read(tty_fd, &hello_req, sizeof(hello_req));
+ if (rc < (int) sizeof(hello_req)) {
+ printf("error receiving hello, wrong packet size\n");
+ return -1;
+ }
+
+ rc = check_mode(hello_req.mode, mode);
+ if (rc < 0) {
+ printf("mode %d is not the expected mode %d\n",
+ hello_req.mode, mode);
+ return -1;
+ }
+
+ hello_resp.header.command = SAH_COMMAND_HELLO_RESP;
+ hello_resp.header.packet_size = sizeof(hello_resp);
+ hello_resp.version = hello_req.version;
+ hello_resp.min_version = hello_req.min_version;
+ hello_resp.status = 0;
+ hello_resp.mode = hello_req.mode;
+
+ rc = write(tty_fd, &hello_resp, sizeof(hello_resp));
+ if (rc < (int) sizeof(hello_resp)) {
+ printf("failed to write hello response\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int hello_handshake(int tty_fd, int mode)
+{
+ struct sah_header header;
+ int rc;
+
+ rc = read(tty_fd, &header, sizeof(header));
+ if (rc < (int) sizeof(header)) {
+ printf("failed to receive header for hello request\n");
+ return -1;
+ } else if (header.command != SAH_COMMAND_HELLO_REQ) {
+ printf("error receiving hello, received command %d\n",
+ header.command);
+ return -1;
+ }
+
+ rc = hello_response(tty_fd, mode);
+ if (rc < 0) {
+ printf("failed to send hello response\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int file_for_id(unsigned int id, char **file)
+{
+ switch (id) {
+ case 6:
+ *file = FILE_APPS;
+ break;
+ case 8:
+ *file = FILE_DSP1;
+ break;
+ case 12:
+ *file = FILE_DSP2;
+ break;
+ case 16:
+ *file = FILE_EFS1;
+ break;
+ case 17:
+ *file = FILE_EFS2;
+ break;
+ case 20:
+ *file = FILE_EFS3;
+ break;
+ case 21:
+ *file = FILE_SBL1;
+ break;
+ case 22:
+ *file = FILE_SBL2;
+ break;
+ case 23:
+ *file = FILE_RPM;
+ break;
+ case 28:
+ *file = FILE_DSP3;
+ break;
+ case 29:
+ *file = FILE_ACDB;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int send_data(int tty_fd, struct sah_header *header)
+{
+ struct sah_data_req data_req;
+ char *file = NULL;
+ int file_fd;
+ char file_data[MAX_DATA_SEND_SIZE];
+ int rc;
+
+ rc = read(tty_fd, header, sizeof(*header));
+ if (rc < (int) sizeof(header)) {
+ printf("failed to receive header for data request\n");
+ return -1;
+ }
+
+ if (header->command == SAH_COMMAND_DATA_END_REQ)
+ return 1;
+
+ rc = read(tty_fd, &data_req, sizeof(data_req));
+ if (rc < (int) sizeof(data_req)) {
+ printf("error receiving data req\n");
+ return -1;
+ }
+
+ if(data_req.size > MAX_DATA_SEND_SIZE) {
+ printf("requested data size is too big\n");
+ return -1;
+ }
+
+ rc = file_for_id(data_req.id, &file);
+ if (rc < 0) {
+ printf("failed to identify requested file\n");
+ return -1;
+ }
+
+ file_fd = open(file, O_RDONLY);
+ if (file_fd < 0) {
+ printf("failed to open requested file\n");
+ return -1;
+ }
+
+ lseek(file_fd, data_req.offset, SEEK_SET);
+
+ rc = read(file_fd, &file_data, data_req.size);
+ if (rc < (int) data_req.size) {
+ printf("failed to read data from file\n");
+ return -1;
+ }
+
+ write(tty_fd, &file_data, data_req.size);
+ if (rc < (int) data_req.size) {
+ printf("failed to send data\n");
+ }
+
+ return 0;
+}
+
+int send_file(int tty_fd, struct sah_data_end_ack *data_end_ack)
+{
+ struct sah_header header;
+ struct sah_data_end_req data_end_req;
+ int rc;
+
+ rc = hello_handshake(tty_fd, SAH_MODE_TRANSFER_PENDING);
+ if (rc < 0) {
+ printf("failed to do hello handshake\n");
+ return -1;
+ }
+
+ do {
+ rc = send_data(tty_fd, &header);
+ if (rc < 0) {
+ printf("error while sending data\n");
+ return -1;
+ }
+ } while (header.command == SAH_COMMAND_DATA_REQ);
+
+ rc = read(tty_fd, &data_end_req, sizeof(data_end_req));
+ if (rc < (int) sizeof(data_end_req)) {
+ printf("error receiving data end request\n");
+ return -1;
+ }
+
+ if (data_end_req.status != 0) {
+ printf("file transfer end status is nonzero\n");
+ return -1;
+ }
+
+ printf("id %d: file transfer complete\n", data_end_req.id);
+
+ header.command = SAH_COMMAND_DATA_END_RESP;
+ header.packet_size = 8;
+ rc = write(tty_fd, &header, sizeof(header));
+ if (rc < (int) sizeof(header)) {
+ printf("failed to write data end response\n");
+ return -1;
+ }
+
+ rc = read(tty_fd, data_end_ack, sizeof(*data_end_ack));
+ if (rc < (int) sizeof(*data_end_ack)
+ || data_end_ack->header.command != SAH_COMMAND_DATA_END_ACK) {
+ printf("error receiving data end ack\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int check_efs_file_request(unsigned char name[20])
+{
+ unsigned char efs1[20] = SYNC_EFS1;
+ unsigned char efs2[20] = SYNC_EFS2;
+
+ if(memcmp(name, efs1, 20) == 0 || memcmp(name, efs2, 20) == 0)
+ return 0;
+ else
+ return -1;
+}
+
+int request_efs_data(int tty_fd,
+ struct sah_memory_read_req memory_read_req)
+{
+ char file_data[MAX_DATA_SEND_SIZE];
+ int rc;
+
+ rc = write(tty_fd, &memory_read_req, sizeof(memory_read_req));
+ if (rc < (int) sizeof(memory_read_req)) {
+ printf("failed to send memory read request for table\n");
+ return -1;
+ }
+
+ rc = read(tty_fd, &file_data, memory_read_req.size);
+ if (rc < (int) memory_read_req.size) {
+ printf("failed to read memory table data\n");
+ return -1;
+ }
+
+ printf("successfully received EFS data\n");
+ printf("TODO: implement writing data to EFS partition\n");
+
+ return 0;
+}
+
+int efs_sync(int tty_fd)
+{
+ struct sah_memory_debug_req memory_debug_req;
+ struct sah_memory_read_req memory_read_req;
+ struct sah_memory_table memory_table;
+ struct sah_header header;
+ int i = 0;
+ int rc;
+
+ rc = read(tty_fd, &memory_debug_req, sizeof(memory_debug_req));
+ if (rc < (int) sizeof(memory_debug_req)) {
+ printf("failed to receive memory debug data\n");
+ return -1;
+ }
+
+ memory_read_req.header.command = SAH_COMMAND_MEMORY_READ_REQ;
+ memory_read_req.header.packet_size = 16;
+ memory_read_req.address = memory_debug_req.address;
+ memory_read_req.size = memory_debug_req.size;
+ rc = write(tty_fd, &memory_read_req, sizeof(memory_read_req));
+ if (rc < (int) sizeof(memory_read_req)) {
+ printf("failed to send initial memory read request\n");
+ return -1;
+ }
+
+ rc = read(tty_fd, &memory_table, sizeof(memory_table));
+ if (rc < (int) sizeof(memory_table)) {
+ printf("failed to receive memory table\n");
+ return -1;
+ }
+
+ printf("requested file %s with address %d and size %d\n",
+ memory_table.file, memory_table.address,
+ memory_table.size);
+
+ rc = check_efs_file_request(memory_table.file);
+ if (rc < 0) {
+ printf("access to requested file is not allowed\n");
+ return -1;
+ }
+
+ if( memory_table.size > MAX_DATA_SEND_SIZE) {
+ printf("requested memory table size is too big\n");
+ return -1;
+ }
+
+ memory_read_req.address = memory_table.address;
+ memory_read_req.size = memory_table.size;
+ do {
+ rc = request_efs_data(tty_fd, memory_read_req);
+ // abort after 3 retries
+ if (i++ > 2)
+ break;
+ } while (rc < 0);
+
+ header.command = SAH_COMMAND_RESET_REQ;
+ header.packet_size = 8;
+ rc = write(tty_fd, &header, sizeof(header));
+ if (rc < (int) sizeof(header)) {
+ printf("failed to send reset request\n");
+ return -1;
+ }
+
+ rc = read(tty_fd, &header, sizeof(header));
+ if (rc < (int) sizeof(header)) {
+ printf("error receiving reset response\n");
+ return -1;
+ } else if (header.command != SAH_COMMAND_RESET_RESP) {
+ printf("received command %d instead of reset response\n",
+ header.command);
+ return -1;
+ }
+
+ return 0;
+}
+
+int handle_memory_debug(int tty_fd)
+{
+ struct sah_header header;
+ int rc;
+
+ rc = read(tty_fd, &header, sizeof(header));
+ if (rc < (int) sizeof(header)) {
+ printf("failed to receive header for command\n");
+ return -1;
+ }
+
+ switch (header.command) {
+ case SAH_COMMAND_HELLO_REQ:
+ printf("received hello\n");
+ rc = hello_response(tty_fd, SAH_MODE_MEMORY_DEBUG);
+ if (rc < 0) {
+ printf("failed to send hello response\n");
+ return -1;
+ }
+ printf("sent hello response\n");
+ break;
+ case SAH_COMMAND_MEMORY_DEBUG_REQ:
+ printf("received memory debug command\n");
+ rc = efs_sync(tty_fd);
+ if (rc < 0) {
+ printf("failed to receive EFS data\n");
+ return -1;
+ }
+ printf("successful EFS sync\n");
+ break;
+ default:
+ printf("received unknown command %d with size %d\n",
+ header.command, header.packet_size);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sahara.h b/sahara.h
index c3cf7af..b4b0e7b 100644
--- a/sahara.h
+++ b/sahara.h
@@ -26,14 +26,19 @@
//modes
#define SAH_MODE_TRANSFER_PENDING 0x00
#define SAH_MODE_TRANSFER_COMPLETE 0x01
+#define SAH_MODE_MEMORY_DEBUG 0x02
// commands
-#define SAH_COMMAND_HELLO_REQ 0x01
-#define SAH_COMMAND_HELLO_RESP 0x02
-#define SAH_COMMAND_DATA_REQ 0x03
-#define SAH_COMMAND_DATA_END_REQ 0x04
-#define SAH_COMMAND_DATA_END_RESP 0x05
-#define SAH_COMMAND_DATA_END_ACK 0x06
+#define SAH_COMMAND_HELLO_REQ 0x01
+#define SAH_COMMAND_HELLO_RESP 0x02
+#define SAH_COMMAND_DATA_REQ 0x03
+#define SAH_COMMAND_DATA_END_REQ 0x04
+#define SAH_COMMAND_DATA_END_RESP 0x05
+#define SAH_COMMAND_DATA_END_ACK 0x06
+#define SAH_COMMAND_RESET_REQ 0x07
+#define SAH_COMMAND_RESET_RESP 0x08
+#define SAH_COMMAND_MEMORY_DEBUG_REQ 0x09
+#define SAH_COMMAND_MEMORY_READ_REQ 0x0A
struct sah_header {
unsigned int command;
@@ -41,7 +46,6 @@ struct sah_header {
} __attribute__((__packed__));
struct sah_hello_req {
- struct sah_header header;
unsigned int version;
unsigned int min_version;
unsigned int not_needed;
@@ -74,4 +78,29 @@ struct sah_data_end_ack {
unsigned int status; // 0 more file requests to come, 1 complete
} __attribute__((__packed__));
+struct sah_memory_debug_req {
+ unsigned int address;
+ unsigned int size;
+} __attribute__((__packed__));
+
+struct sah_memory_read_req {
+ struct sah_header header;
+ unsigned int address;
+ unsigned int size;
+} __attribute__((__packed__));
+
+// response after a memory read request
+struct sah_memory_table {
+ unsigned int unknown;
+ unsigned int address;
+ unsigned int size;
+ unsigned char empty[20];
+ unsigned char file[20];
+} __attribute__((__packed__));
+
+int hello_response(int tty_fd, int mode);
+int hello_handshake(int tty_fd, int mode);
+int send_file(int tty_fd, struct sah_data_end_ack *data_end_ack);
+int handle_memory_debug(int tty_fd);
+
#endif