2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
6 * libsamsung-ipc is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * libsamsung-ipc is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
30 #include <openssl/md5.h>
32 #include <samsung-ipc.h>
36 void md5hash2string(char *out, unsigned char *in)
40 for (i=0; i < MD5_DIGEST_LENGTH; i++)
42 /* After the first iteration, we override \0. */
44 sprintf(out, "0%x", *in);
46 sprintf(out, "%x", *in);
52 char *nv_data_path(struct ipc_client *client)
55 client->nv_data_specs == NULL ||
56 client->nv_data_specs->nv_data_path == NULL)
57 return NV_DATA_PATH_DEFAULT;
59 return client->nv_data_specs->nv_data_path;
62 char *nv_data_md5_path(struct ipc_client *client)
65 client->nv_data_specs == NULL ||
66 client->nv_data_specs->nv_data_md5_path == NULL)
67 return NV_DATA_MD5_PATH_DEFAULT;
69 return client->nv_data_specs->nv_data_md5_path;
72 char *nv_data_bak_path(struct ipc_client *client)
75 client->nv_data_specs == NULL ||
76 client->nv_data_specs->nv_data_bak_path == NULL)
77 return NV_DATA_BAK_PATH_DEFAULT;
79 return client->nv_data_specs->nv_data_bak_path;
82 char *nv_data_md5_bak_path(struct ipc_client *client)
85 client->nv_data_specs == NULL ||
86 client->nv_data_specs->nv_data_md5_bak_path == NULL)
87 return NV_DATA_MD5_BAK_PATH_DEFAULT;
89 return client->nv_data_specs->nv_data_md5_bak_path;
92 char *nv_state_path(struct ipc_client *client)
95 client->nv_data_specs == NULL ||
96 client->nv_data_specs->nv_state_path == NULL)
97 return NV_STATE_PATH_DEFAULT;
99 return client->nv_data_specs->nv_state_path;
102 char *nv_data_secret(struct ipc_client *client)
104 if (client == NULL ||
105 client->nv_data_specs == NULL ||
106 client->nv_data_specs->nv_data_secret == NULL)
107 return NV_DATA_SECRET_DEFAULT;
109 return client->nv_data_specs->nv_data_secret;
112 int nv_data_size(struct ipc_client *client)
114 if (client == NULL ||
115 client->nv_data_specs == NULL ||
116 client->nv_data_specs->nv_data_size == 0)
117 return NV_DATA_SIZE_DEFAULT;
119 return client->nv_data_specs->nv_data_size;
122 int nv_data_chunk_size(struct ipc_client *client)
124 if (client == NULL ||
125 client->nv_data_specs == NULL ||
126 client->nv_data_specs->nv_data_chunk_size == 0)
127 return NV_DATA_CHUNK_SIZE_DEFAULT;
129 return client->nv_data_specs->nv_data_chunk_size;
132 void nv_data_generate(struct ipc_client *client)
134 ipc_client_log(client, "This feature isn't present yet");
136 // nv_data_backup_create();
139 void nv_data_md5_compute(void *data_p, int size, char *secret, void *hash)
143 // MD5((unsigned char *)nv_data_p, nv_data_stat.st_size, nv_data_md5_hash);
146 MD5_Update(&ctx, data_p, size);
147 MD5_Update(&ctx, secret, strlen(secret));
148 MD5_Final(hash, &ctx);
151 void nv_data_md5_generate(struct ipc_client *client)
153 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
154 char *nv_data_md5_hash_string = NULL;
155 void *nv_data_p = NULL;
159 ipc_client_log(client, "nv_data_md5_generate: enter");
161 ipc_client_log(client, "nv_data_md5_generate: generating MD5 hash");
162 nv_data_p=ipc_client_file_read(client, nv_data_path(client),
163 nv_data_size(client), nv_data_chunk_size(client));
164 nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
167 /* Alloc the memory for the md5 hash string. */
168 nv_data_md5_hash_string = malloc(MD5_STRING_SIZE);
169 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
171 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
173 ipc_client_log(client, "nv_data_md5_generate: new MD5 hash is %s", nv_data_md5_hash_string);
175 ipc_client_log(client, "nv_data_md5_generate: writing MD5 hash");
177 /* Write the MD5 hash in nv_data.bin.md5. */
178 fd = open(nv_data_md5_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
181 ipc_client_log(client, "nv_data_md5_generate: fd open failed");
185 rc = write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
188 ipc_client_log(client, "nv_data_md5_generate: failed to write MD5 hash to file");
196 if (nv_data_md5_hash_string != NULL)
197 free(nv_data_md5_hash_string);
199 ipc_client_log(client, "nv_data_md5_generate: exit");
202 void nv_data_backup_create(struct ipc_client *client)
204 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
205 char *nv_data_md5_hash_string = NULL;
206 char *nv_data_md5_hash_read = NULL;
207 int nv_data_write_tries = 0;
210 void *nv_data_p = NULL;
211 void *nv_data_bak_p = NULL;
218 ipc_client_log(client, "nv_data_backup_create: enter");
220 if (stat(nv_data_path(client), &nv_stat) < 0)
222 ipc_client_log(client, "nv_data_backup_create: nv_data.bin missing");
223 nv_data_generate(client);
226 if (nv_stat.st_size != nv_data_size(client))
228 ipc_client_log(client, "nv_data_backup_create: wrong nv_data.bin size");
229 nv_data_generate(client);
233 if (stat(nv_data_md5_path(client), &nv_stat) < 0)
235 ipc_client_log(client, "nv_data_backup_create: nv_data.bin.md5 missing");
236 nv_data_generate(client);
240 /* Alloc the memory for the md5 hashes strings. */
241 nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
242 nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);
244 memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
245 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
247 /* Read the content of the backup file. */
248 nv_data_p=ipc_client_file_read(client, nv_data_path(client),
249 nv_data_size(client), nv_data_chunk_size(client));
251 /* Compute the backup file MD5 hash. */
252 nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
253 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
255 /* Read the stored backup file MD5 hash. */
256 fd = open(nv_data_md5_path(client), O_RDONLY);
259 ipc_client_log(client, "nv_data_backup_create: failed to openstored backup file with MD5 hash");
263 rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
266 ipc_client_log(client, "nv_data_backup_create: failed to read MD5 hash from backup file");
273 /* Add 0x0 to end the string: not sure this is always part of the file. */
274 nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';
276 ipc_client_log(client, "nv_data_backup_create: backup file computed MD5: %s read MD5: %s",
277 nv_data_md5_hash_string, nv_data_md5_hash_read);
279 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
281 ipc_client_log(client, "nv_data_backup_create: MD5 hash mismatch on backup file");
282 ipc_client_log(client, "nv_data_backup_create: Consider the computed one as correct");
284 fd = open(nv_data_md5_path(client), O_WRONLY);
287 ipc_client_log(client, "nv_data_backup_create: failed to open file with MD5 hash of data file");
291 rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
294 ipc_client_log(client, "nv_data_backup_create: failed to read MD5 hash for data file from file");
301 nv_data_backup_generate(client);
302 nv_data_backup_create(client);
307 /* Assume the read string is the computated one */
308 memcpy(nv_data_md5_hash_read, nv_data_md5_hash_string, MD5_STRING_SIZE);
309 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
311 nv_data_backup_create_write:
312 while (nv_data_write_tries < 5)
314 ipc_client_log(client, "nv_data_backup_create: .nv_data.bak write try #%d", nv_data_write_tries + 1);
316 fd = open(nv_data_bak_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
319 ipc_client_log(client, "nv_data_backup_create: negative fd while opening /efs/.nv_data.bak, error: %s", strerror(errno));
320 nv_data_write_tries++;
324 rc = write(fd, nv_data_p, nv_data_size(client));
325 if (rc < nv_data_size(client))
327 ipc_client_log(client, "nv_data_backup_create: wrote less (%d) than what we expected (%d) on /efs/.nv_data.bak, error: %s", strerror(errno));
329 nv_data_write_tries++;
337 if (nv_data_write_tries == 5)
339 ipc_client_log(client, "nv_data_backup_create: writing nv_data.bin to .nv_data.bak failed too many times");
340 unlink(nv_data_bak_path(client));
344 /* Read the newly-written .nv_data.bak. */
345 nv_data_bak_p = ipc_client_file_read(client, nv_data_bak_path(client),
346 nv_data_size(client), nv_data_chunk_size(client));
348 /* Compute the MD5 hash for nv_data.bin. */
349 nv_data_md5_compute(nv_data_bak_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
350 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
352 if (nv_data_bak_p != NULL)
355 ipc_client_log(client, "nv_data_backup_create: written file computed MD5: %s read MD5: %s",
356 nv_data_md5_hash_string, nv_data_md5_hash_read);
358 /* Make sure both hashes are the same. */
359 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
361 ipc_client_log(client, "nv_data_backup_create: MD5 hash mismatch on written file");
362 ipc_client_log(client, "nv_data_backup_create: Writing again");
364 goto nv_data_backup_create_write;
367 /* Write the MD5 hash in .nv_data.bak.md5. */
368 fd = open(nv_data_md5_bak_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
371 ipc_client_log(client, "nv_data_backup_create: failed to open MD5 hash file");
375 rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
378 ipc_client_log(client, "nv_data_backup_create: failed to write MD5 hash to file");
384 /* Write the correct .nv_state. */
385 fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
388 ipc_client_log(client, "nv_data_backup_create: failed to open NV state file");
393 rc = write(fd, &data, sizeof(data));
396 ipc_client_log(client, "nv_data_backup_create: failed to write state of NV data");
404 if (nv_data_p != NULL)
406 if (nv_data_md5_hash_string != NULL)
407 free(nv_data_md5_hash_string);
408 if (nv_data_md5_hash_read)
409 free(nv_data_md5_hash_read);
411 ipc_client_log(client, "nv_data_backup_create: exit");
414 void nv_data_backup_restore(struct ipc_client *client)
416 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
417 char *nv_data_md5_hash_string = NULL;
418 char *nv_data_md5_hash_read = NULL;
419 int nv_data_write_tries = 0;
422 void *nv_data_p = NULL;
423 void *nv_data_bak_p = NULL;
430 ipc_client_log(client, "nv_data_backup_restore: enter");
432 if (stat(nv_data_bak_path(client), &nv_stat) < 0)
434 ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak missing");
435 nv_data_generate(client);
436 nv_data_backup_create(client);
440 if (nv_stat.st_size != nv_data_size(client))
442 ipc_client_log(client, "nv_data_backup_restore: wrong .nv_data.bak size");
443 nv_data_generate(client);
444 nv_data_backup_create(client);
448 if (stat(nv_data_md5_bak_path(client), &nv_stat) < 0)
450 ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak.md5 missing");
451 nv_data_generate(client);
452 nv_data_backup_create(client);
456 /* Alloc the memory for the md5 hashes strings. */
457 nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
458 nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);
460 memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
461 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
463 /* Read the content of the backup file. */
464 nv_data_bak_p=ipc_client_file_read(client, nv_data_bak_path(client),
465 nv_data_size(client), nv_data_chunk_size(client));
467 /* Compute the backup file MD5 hash. */
468 nv_data_md5_compute(nv_data_bak_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
469 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
471 /* Read the stored backup file MD5 hash. */
472 fd=open(nv_data_md5_bak_path(client), O_RDONLY);
473 rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
476 ipc_client_log(client, "nv_data_backup_restore: Failed to read md5 hash for stored back file");
483 /* Add 0x0 to end the string: not sure this is always part of the file. */
484 nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';
486 ipc_client_log(client, "nv_data_backup_restore: backup file computed MD5: %s read MD5: %s",
487 nv_data_md5_hash_string, nv_data_md5_hash_read);
489 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
491 ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on backup file");
492 ipc_client_log(client, "nv_data_backup_restore: Consider the computed one as correct");
494 fd = open(nv_data_md5_bak_path(client), O_WRONLY);
497 ipc_client_log(client, "nv_data_backup_restore: failed to open MD5 hash backup file");
501 rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
504 ipc_client_log(client, "nv_data_backup_restore: failed to read MD5 hash from backup file");
512 nv_data_backup_generate(client);
513 nv_data_backup_create(client);
518 /* Assume the read string is the computated one */
519 memcpy(nv_data_md5_hash_read, nv_data_md5_hash_string, MD5_STRING_SIZE);
520 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
522 nv_data_backup_restore_write:
523 while (nv_data_write_tries < 5)
525 ipc_client_log(client, "nv_data_backup_restore: nv_data.bin write try #%d", nv_data_write_tries + 1);
527 fd=open(nv_data_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
530 ipc_client_log(client, "nv_data_backup_restore: negative fd while opening /efs/nv_data.bin, error: %s", strerror(errno));
531 nv_data_write_tries++;
535 rc = write(fd, nv_data_bak_p, nv_data_size(client));
536 if (rc < nv_data_size(client))
538 ipc_client_log(client, "nv_data_backup_restore: wrote less (%d) than what we expected (%d) on /efs/nv_data.bin, error: %s", strerror(errno));
540 nv_data_write_tries++;
548 if (nv_data_write_tries == 5)
550 ipc_client_log(client, "nv_data_backup_restore: writing the backup to nv_data.bin failed too many times");
551 unlink(nv_data_path(client));
555 /* Read the newly-written nv_data.bin. */
556 nv_data_p=ipc_client_file_read(client, nv_data_path(client),
557 nv_data_size(client), nv_data_chunk_size(client));
559 /* Compute the MD5 hash for nv_data.bin. */
560 nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
561 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
563 if (nv_data_p != NULL)
569 ipc_client_log(client, "nv_data_backup_restore: written file computed MD5: %s read MD5: %s",
570 nv_data_md5_hash_string, nv_data_md5_hash_read);
572 /* Make sure both hashes are the same. */
573 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
575 ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on written file");
576 ipc_client_log(client, "nv_data_backup_restore: Writing again");
578 goto nv_data_backup_restore_write;
581 /* Write the MD5 hash in nv_data.bin.md5. */
582 fd = open(nv_data_md5_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
585 ipc_client_log(client, "nv_data_backup_restore: failed to open file with MD5 hash");
589 rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
592 ipc_client_log(client, "nv_data_backup_restore: failed to write MD5 hash to file");
598 /* Write the correct .nv_state. */
599 fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
602 ipc_client_log(client, "nv_data_backup_restore: failed to open NV state file");
607 rc = write(fd, &data, sizeof(data));
610 ipc_client_log(client, "nv_data_backup_restore: failed to write state to file");
618 if (nv_data_bak_p != NULL)
620 if (nv_data_md5_hash_string != NULL)
621 free(nv_data_md5_hash_string);
622 if (nv_data_md5_hash_read != NULL)
623 free(nv_data_md5_hash_read);
625 ipc_client_log(client, "nv_data_backup_restore: exit");
628 int nv_data_check(struct ipc_client *client)
635 ipc_client_log(client, "nv_data_check: enter");
637 if (stat(nv_data_path(client), &nv_stat) < 0)
639 ipc_client_log(client, "nv_data_check: nv_data.bin missing");
640 nv_data_backup_restore(client);
641 stat(nv_data_path(client), &nv_stat);
644 if (nv_stat.st_size != nv_data_size(client))
646 ipc_client_log(client, "nv_data_check: wrong nv_data.bin size");
647 nv_data_backup_restore(client);
650 if (stat(nv_data_md5_path(client), &nv_stat) < 0)
652 ipc_client_log(client, "nv_data_check: nv_data.bin.md5 missing");
653 nv_data_backup_restore(client);
656 if (stat(nv_data_bak_path(client), &nv_stat) < 0 || stat(nv_data_md5_bak_path(client), &nv_stat) < 0)
658 ipc_client_log(client, "nv_data_check: .nv_data.bak or .nv_data.bak.md5 missing");
659 nv_data_backup_create(client);
662 nv_state_fd=open(nv_state_path(client), O_RDONLY);
664 if (nv_state_fd < 0 || fstat(nv_state_fd, &nv_stat) < 0)
666 ipc_client_log(client, "nv_data_check: .nv_state missing");
667 nv_data_backup_restore(client);
670 rc = read(nv_state_fd, &nv_state, sizeof(nv_state));
673 ipc_client_log(client, "nv_data_check: couldn't read state of NV item from file");
681 ipc_client_log(client, "nv_data_check: bad nv_state");
682 nv_data_backup_restore(client);
685 ipc_client_log(client, "nv_data_check: everything should be alright");
686 ipc_client_log(client, "nv_data_check: exit");
691 int nv_data_md5_check(struct ipc_client *client)
694 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
695 char *nv_data_md5_hash_string = NULL;
696 char *nv_data_md5_hash_read = NULL;
697 void *nv_data_p = NULL;
702 ipc_client_log(client, "nv_data_md5_check: enter");
704 nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
705 nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);
707 memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
708 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
710 nv_data_p=ipc_client_file_read(client, nv_data_path(client),
711 nv_data_size(client), nv_data_chunk_size(client));
714 nv_data_md5_compute(data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
716 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
720 fd=open(nv_data_md5_path(client), O_RDONLY);
722 /* Read the md5 stored in the file. */
723 rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
726 ipc_client_log(client, "nv_data_md5_check: Can't read md5 hash from file");
730 /* Add 0x0 to end the string: not sure this is part of the file. */
731 nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';
733 ipc_client_log(client, "nv_data_md5_check: computed MD5: %s read MD5: %s",
734 nv_data_md5_hash_string, nv_data_md5_hash_read);
736 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
738 ipc_client_log(client, "nv_data_md5_check: MD5 hash mismatch");
739 nv_data_backup_restore(client);
742 if (nv_data_md5_hash_string != NULL)
743 free(nv_data_md5_hash_string);
744 if (nv_data_md5_hash_read != NULL)
745 free(nv_data_md5_hash_read);
747 ipc_client_log(client, "nv_data_md5_check: exit");
752 int nv_data_read(struct ipc_client *client, int offset, int length, char *buf)
757 ipc_client_log(client, "nv_data_read: enter");
759 if (offset < 0 || length <= 0) {
760 ipc_client_log(client, "nv_data_read: offset < 0 or length <= 0");
765 ipc_client_log(client, "nv_data_read: provided output buf is NULL");
769 if (nv_data_check(client) < 0)
772 fd = open(nv_data_path(client), O_RDONLY);
774 ipc_client_log(client, "nv_data_read: nv_data file fd is negative");
778 lseek(fd, offset, SEEK_SET);
780 rc = read(fd, buf, length);
782 ipc_client_log(client, "nv_data_read: read less than what we expected");
786 ipc_client_log(client, "nv_data_read: exit");
791 int nv_data_write(struct ipc_client *client, int offset, int length, char *buf)
796 ipc_client_log(client, "nv_data_write: enter");
798 if (offset < 0 || length <= 0) {
799 ipc_client_log(client, "nv_data_write: offset or length <= 0");
804 ipc_client_log(client, "nv_data_write: provided input buf is NULL");
808 if (nv_data_check(client) < 0)
811 fd = open(nv_data_path(client), O_WRONLY);
813 ipc_client_log(client, "nv_data_write: nv_data file fd is negative");
817 lseek(fd, offset, SEEK_SET);
819 rc = write(fd, buf, length);
824 ipc_client_log(client, "nv_data_write: wrote less (%d) than what we expected (%d), error: %s, restoring backup", rc, length, strerror(errno));
825 nv_data_backup_restore(client);
829 ipc_client_log(client, "nv_data_write: writing new md5sum");
830 nv_data_md5_generate(client);
832 ipc_client_log(client, "nv_data_write: exit");
837 void ipc_rfs_send_io_confirm_for_nv_read_item(struct ipc_client *client,
838 struct ipc_message_info *info)
840 struct ipc_rfs_io *rfs_io = (struct ipc_rfs_io *) info->data;
841 struct ipc_rfs_io_confirm *rfs_io_conf;
847 ipc_client_log(client, "ERROR: Request message is invalid: aseq = %i", info->aseq);
851 rfs_io_conf = malloc(rfs_io->length + sizeof(struct ipc_rfs_io_confirm));
852 memset(rfs_io_conf, 0, rfs_io->length + sizeof(struct ipc_rfs_io_confirm));
853 rfs_data = rfs_io_conf + sizeof(struct ipc_rfs_io_confirm);
855 ipc_client_log(client, "Asked to read 0x%x bytes at offset 0x%x", rfs_io->length, rfs_io->offset);
856 rc = nv_data_read(client, rfs_io->offset, rfs_io->length, rfs_data);
859 ipc_client_log(client, "Read rfs_data dump:");
860 ipc_client_hex_dump(client, rfs_data, rfs_io->length);
863 ipc_client_log(client, "Preparing RFS IO Confirm message (rc is %d)", rc);
864 rfs_io_conf->confirm = rc < 0 ? 0 : 1;
865 rfs_io_conf->offset = rfs_io->offset;
866 rfs_io_conf->length = rfs_io->length;
868 ipc_client_send(client, IPC_RFS_NV_READ_ITEM, 0, (unsigned char *) rfs_io_conf,
869 rfs_io->length + sizeof(struct ipc_rfs_io_confirm), info->aseq);
873 void ipc_rfs_send_io_confirm_for_nv_write_item(struct ipc_client *client,
874 struct ipc_message_info *info)
876 struct ipc_rfs_io *rfs_io = (struct ipc_rfs_io *) info->data;
877 struct ipc_rfs_io_confirm *rfs_io_conf;
883 ipc_client_log(client, "ERROR: Request message is invalid: aseq = %i", info->aseq);
887 rfs_data = info->data + sizeof(struct ipc_rfs_io);
890 ipc_client_log(client, "Write rfs_data dump:");
891 ipc_client_hex_dump(client, rfs_data, rfs_io->length);
894 ipc_client_log(client, "Asked to write 0x%x bytes at offset 0x%x", rfs_io->length, rfs_io->offset);
895 rc = nv_data_write(client, rfs_io->offset, rfs_io->length, rfs_data);
897 ipc_client_log(client, "Sending RFS IO Confirm message (rc is %d)", rc);
898 rfs_io_conf = (struct ipc_rfs_io_confirm*) malloc(sizeof(struct ipc_rfs_io_confirm));
899 rfs_io_conf->confirm = rc < 0 ? 0 : 1;
900 rfs_io_conf->offset = rfs_io->offset;
901 rfs_io_conf->length = rfs_io->length;
903 ipc_client_send(client, IPC_RFS_NV_WRITE_ITEM, 0, (unsigned char *) rfs_io_conf,
904 sizeof(struct ipc_rfs_io_confirm), info->aseq);
908 // vim:ts=4:sw=4:expandtab