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>
37 void md5hash2string(char *out, unsigned char *in)
41 for (i = 0; i < MD5_DIGEST_LENGTH; i++)
43 /* After the first iteration, we override \0. */
45 sprintf(out, "0%x", *in);
47 sprintf(out, "%x", *in);
54 char *nv_data_path(struct ipc_client *client)
57 client->nv_data_specs == NULL ||
58 client->nv_data_specs->nv_data_path == NULL)
59 return NV_DATA_PATH_DEFAULT;
61 return client->nv_data_specs->nv_data_path;
64 char *nv_data_md5_path(struct ipc_client *client)
67 client->nv_data_specs == NULL ||
68 client->nv_data_specs->nv_data_md5_path == NULL)
69 return NV_DATA_MD5_PATH_DEFAULT;
71 return client->nv_data_specs->nv_data_md5_path;
74 char *nv_data_bak_path(struct ipc_client *client)
77 client->nv_data_specs == NULL ||
78 client->nv_data_specs->nv_data_bak_path == NULL)
79 return NV_DATA_BAK_PATH_DEFAULT;
81 return client->nv_data_specs->nv_data_bak_path;
84 char *nv_data_md5_bak_path(struct ipc_client *client)
87 client->nv_data_specs == NULL ||
88 client->nv_data_specs->nv_data_md5_bak_path == NULL)
89 return NV_DATA_MD5_BAK_PATH_DEFAULT;
91 return client->nv_data_specs->nv_data_md5_bak_path;
94 char *nv_state_path(struct ipc_client *client)
97 client->nv_data_specs == NULL ||
98 client->nv_data_specs->nv_state_path == NULL)
99 return NV_STATE_PATH_DEFAULT;
101 return client->nv_data_specs->nv_state_path;
104 char *nv_data_secret(struct ipc_client *client)
106 if (client == NULL ||
107 client->nv_data_specs == NULL ||
108 client->nv_data_specs->nv_data_secret == NULL)
109 return NV_DATA_SECRET_DEFAULT;
111 return client->nv_data_specs->nv_data_secret;
114 int nv_data_size(struct ipc_client *client)
116 if (client == NULL ||
117 client->nv_data_specs == NULL ||
118 client->nv_data_specs->nv_data_size == 0)
119 return NV_DATA_SIZE_DEFAULT;
121 return client->nv_data_specs->nv_data_size;
124 int nv_data_chunk_size(struct ipc_client *client)
126 if (client == NULL ||
127 client->nv_data_specs == NULL ||
128 client->nv_data_specs->nv_data_chunk_size == 0)
129 return NV_DATA_CHUNK_SIZE_DEFAULT;
131 return client->nv_data_specs->nv_data_chunk_size;
134 void nv_data_generate(struct ipc_client *client)
139 void nv_data_md5_compute(void *data_p, int size, char *secret, void *hash)
144 MD5_Update(&ctx, data_p, size);
145 MD5_Update(&ctx, secret, strlen(secret));
146 MD5_Final(hash, &ctx);
149 void nv_data_md5_generate(struct ipc_client *client)
151 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
152 char *nv_data_md5_hash_string = NULL;
153 void *nv_data_p = NULL;
157 ipc_client_log(client, "nv_data_md5_generate: enter");
159 ipc_client_log(client, "nv_data_md5_generate: generating MD5 hash");
160 nv_data_p = file_data_read(nv_data_path(client),
161 nv_data_size(client), nv_data_chunk_size(client));
162 nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
165 /* Alloc the memory for the md5 hash string. */
166 nv_data_md5_hash_string = malloc(MD5_STRING_SIZE);
167 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
169 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
171 ipc_client_log(client, "nv_data_md5_generate: new MD5 hash is %s", nv_data_md5_hash_string);
173 ipc_client_log(client, "nv_data_md5_generate: writing MD5 hash");
175 /* Write the MD5 hash in nv_data.bin.md5. */
176 fd = open(nv_data_md5_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
179 ipc_client_log(client, "nv_data_md5_generate: fd open failed");
183 rc = write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
186 ipc_client_log(client, "nv_data_md5_generate: failed to write MD5 hash to file");
194 if (nv_data_md5_hash_string != NULL)
195 free(nv_data_md5_hash_string);
197 ipc_client_log(client, "nv_data_md5_generate: exit");
200 void nv_data_backup_create(struct ipc_client *client)
202 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
203 char *nv_data_md5_hash_string = NULL;
204 char *nv_data_md5_hash_read = NULL;
205 int nv_data_write_tries = 0;
208 void *nv_data_p = NULL;
209 void *nv_data_bak_p = NULL;
216 ipc_client_log(client, "nv_data_backup_create: enter");
218 if (stat(nv_data_path(client), &nv_stat) < 0)
220 ipc_client_log(client, "nv_data_backup_create: nv_data.bin missing");
221 nv_data_generate(client);
224 if (nv_stat.st_size != nv_data_size(client))
226 ipc_client_log(client, "nv_data_backup_create: wrong nv_data.bin size");
227 nv_data_generate(client);
231 if (stat(nv_data_md5_path(client), &nv_stat) < 0)
233 ipc_client_log(client, "nv_data_backup_create: nv_data.bin.md5 missing");
234 nv_data_generate(client);
238 /* Alloc the memory for the md5 hashes strings. */
239 nv_data_md5_hash_string = malloc(MD5_STRING_SIZE);
240 nv_data_md5_hash_read = malloc(MD5_STRING_SIZE);
242 memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
243 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
245 /* Read the content of the backup file. */
246 nv_data_p = file_data_read(nv_data_path(client),
247 nv_data_size(client), nv_data_chunk_size(client));
249 /* Compute the backup file MD5 hash. */
250 nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
251 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
253 /* Read the stored backup file MD5 hash. */
254 fd = open(nv_data_md5_path(client), O_RDONLY);
257 ipc_client_log(client, "nv_data_backup_create: failed to openstored backup file with MD5 hash");
261 rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
264 ipc_client_log(client, "nv_data_backup_create: failed to read MD5 hash from backup file");
271 /* Add 0x0 to end the string: not sure this is always part of the file. */
272 nv_data_md5_hash_read[MD5_STRING_SIZE - 1] = '\0';
274 ipc_client_log(client, "nv_data_backup_create: backup file computed MD5: %s read MD5: %s",
275 nv_data_md5_hash_string, nv_data_md5_hash_read);
277 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
279 ipc_client_log(client, "nv_data_backup_create: MD5 hash mismatch on backup file");
280 ipc_client_log(client, "nv_data_backup_create: Consider the computed one as correct");
282 fd = open(nv_data_md5_path(client), O_WRONLY);
285 ipc_client_log(client, "nv_data_backup_create: failed to open file with MD5 hash of data file");
289 rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
292 ipc_client_log(client, "nv_data_backup_create: failed to read MD5 hash for data file from file");
299 nv_data_backup_generate(client);
300 nv_data_backup_create(client);
305 /* Assume the read string is the computated one */
306 memcpy(nv_data_md5_hash_read, nv_data_md5_hash_string, MD5_STRING_SIZE);
307 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
309 nv_data_backup_create_write:
310 while (nv_data_write_tries < 5)
312 ipc_client_log(client, "nv_data_backup_create: .nv_data.bak write try #%d", nv_data_write_tries + 1);
314 fd = open(nv_data_bak_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
317 ipc_client_log(client, "nv_data_backup_create: negative fd while opening /efs/.nv_data.bak, error: %s", strerror(errno));
318 nv_data_write_tries++;
322 rc = write(fd, nv_data_p, nv_data_size(client));
323 if (rc < nv_data_size(client))
325 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));
327 nv_data_write_tries++;
335 if (nv_data_write_tries == 5)
337 ipc_client_log(client, "nv_data_backup_create: writing nv_data.bin to .nv_data.bak failed too many times");
338 unlink(nv_data_bak_path(client));
342 /* Read the newly-written .nv_data.bak. */
343 nv_data_bak_p = file_data_read(nv_data_bak_path(client),
344 nv_data_size(client), nv_data_chunk_size(client));
346 /* Compute the MD5 hash for nv_data.bin. */
347 nv_data_md5_compute(nv_data_bak_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
348 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
350 if (nv_data_bak_p != NULL)
353 ipc_client_log(client, "nv_data_backup_create: written file computed MD5: %s read MD5: %s",
354 nv_data_md5_hash_string, nv_data_md5_hash_read);
356 /* Make sure both hashes are the same. */
357 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
359 ipc_client_log(client, "nv_data_backup_create: MD5 hash mismatch on written file");
360 ipc_client_log(client, "nv_data_backup_create: Writing again");
362 goto nv_data_backup_create_write;
365 /* Write the MD5 hash in .nv_data.bak.md5. */
366 fd = open(nv_data_md5_bak_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
369 ipc_client_log(client, "nv_data_backup_create: failed to open MD5 hash file");
373 rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
376 ipc_client_log(client, "nv_data_backup_create: failed to write MD5 hash to file");
382 /* Write the correct .nv_state. */
383 fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
386 ipc_client_log(client, "nv_data_backup_create: failed to open NV state file");
391 rc = write(fd, &data, sizeof(data));
394 ipc_client_log(client, "nv_data_backup_create: failed to write state of NV data");
402 if (nv_data_p != NULL)
404 if (nv_data_md5_hash_string != NULL)
405 free(nv_data_md5_hash_string);
406 if (nv_data_md5_hash_read)
407 free(nv_data_md5_hash_read);
409 ipc_client_log(client, "nv_data_backup_create: exit");
412 void nv_data_backup_restore(struct ipc_client *client)
414 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
415 char *nv_data_md5_hash_string = NULL;
416 char *nv_data_md5_hash_read = NULL;
417 int nv_data_write_tries = 0;
420 void *nv_data_p = NULL;
421 void *nv_data_bak_p = NULL;
428 ipc_client_log(client, "nv_data_backup_restore: enter");
430 if (stat(nv_data_bak_path(client), &nv_stat) < 0)
432 ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak missing");
433 nv_data_generate(client);
434 nv_data_backup_create(client);
438 if (nv_stat.st_size != nv_data_size(client))
440 ipc_client_log(client, "nv_data_backup_restore: wrong .nv_data.bak size");
441 nv_data_generate(client);
442 nv_data_backup_create(client);
446 if (stat(nv_data_md5_bak_path(client), &nv_stat) < 0)
448 ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak.md5 missing");
449 nv_data_generate(client);
450 nv_data_backup_create(client);
454 /* Alloc the memory for the md5 hashes strings. */
455 nv_data_md5_hash_string = malloc(MD5_STRING_SIZE);
456 nv_data_md5_hash_read = malloc(MD5_STRING_SIZE);
458 memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
459 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
461 /* Read the content of the backup file. */
462 nv_data_bak_p = file_data_read(nv_data_bak_path(client),
463 nv_data_size(client), nv_data_chunk_size(client));
465 /* Compute the backup file MD5 hash. */
466 nv_data_md5_compute(nv_data_bak_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
467 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
469 /* Read the stored backup file MD5 hash. */
470 fd = open(nv_data_md5_bak_path(client), O_RDONLY);
471 rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
474 ipc_client_log(client, "nv_data_backup_restore: Failed to read md5 hash for stored back file");
481 /* Add 0x0 to end the string: not sure this is always part of the file. */
482 nv_data_md5_hash_read[MD5_STRING_SIZE - 1] = '\0';
484 ipc_client_log(client, "nv_data_backup_restore: backup file computed MD5: %s read MD5: %s",
485 nv_data_md5_hash_string, nv_data_md5_hash_read);
487 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
489 ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on backup file");
490 ipc_client_log(client, "nv_data_backup_restore: Consider the computed one as correct");
492 fd = open(nv_data_md5_bak_path(client), O_WRONLY);
495 ipc_client_log(client, "nv_data_backup_restore: failed to open MD5 hash backup file");
499 rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
502 ipc_client_log(client, "nv_data_backup_restore: failed to read MD5 hash from backup file");
510 nv_data_backup_generate(client);
511 nv_data_backup_create(client);
516 /* Assume the read string is the computated one */
517 memcpy(nv_data_md5_hash_read, nv_data_md5_hash_string, MD5_STRING_SIZE);
518 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
520 nv_data_backup_restore_write:
521 while (nv_data_write_tries < 5)
523 ipc_client_log(client, "nv_data_backup_restore: nv_data.bin write try #%d", nv_data_write_tries + 1);
525 fd = open(nv_data_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
528 ipc_client_log(client, "nv_data_backup_restore: negative fd while opening /efs/nv_data.bin, error: %s", strerror(errno));
529 nv_data_write_tries++;
533 rc = write(fd, nv_data_bak_p, nv_data_size(client));
534 if (rc < nv_data_size(client))
536 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));
538 nv_data_write_tries++;
546 if (nv_data_write_tries == 5)
548 ipc_client_log(client, "nv_data_backup_restore: writing the backup to nv_data.bin failed too many times");
549 unlink(nv_data_path(client));
553 /* Read the newly-written nv_data.bin. */
554 nv_data_p = file_data_read(nv_data_path(client),
555 nv_data_size(client), nv_data_chunk_size(client));
557 /* Compute the MD5 hash for nv_data.bin. */
558 nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
559 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
561 if (nv_data_p != NULL)
567 ipc_client_log(client, "nv_data_backup_restore: written file computed MD5: %s read MD5: %s",
568 nv_data_md5_hash_string, nv_data_md5_hash_read);
570 /* Make sure both hashes are the same. */
571 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
573 ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on written file");
574 ipc_client_log(client, "nv_data_backup_restore: Writing again");
576 goto nv_data_backup_restore_write;
579 /* Write the MD5 hash in nv_data.bin.md5. */
580 fd = open(nv_data_md5_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
583 ipc_client_log(client, "nv_data_backup_restore: failed to open file with MD5 hash");
587 rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
590 ipc_client_log(client, "nv_data_backup_restore: failed to write MD5 hash to file");
596 /* Write the correct .nv_state. */
597 fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
600 ipc_client_log(client, "nv_data_backup_restore: failed to open NV state file");
605 rc = write(fd, &data, sizeof(data));
608 ipc_client_log(client, "nv_data_backup_restore: failed to write state to file");
616 if (nv_data_bak_p != NULL)
618 if (nv_data_md5_hash_string != NULL)
619 free(nv_data_md5_hash_string);
620 if (nv_data_md5_hash_read != NULL)
621 free(nv_data_md5_hash_read);
623 ipc_client_log(client, "nv_data_backup_restore: exit");
626 int nv_data_check(struct ipc_client *client)
629 int nv_state_fd = -1;
633 ipc_client_log(client, "nv_data_check: enter");
635 if (stat(nv_data_path(client), &nv_stat) < 0)
637 ipc_client_log(client, "nv_data_check: nv_data.bin missing");
638 nv_data_backup_restore(client);
639 stat(nv_data_path(client), &nv_stat);
642 if (nv_stat.st_size != nv_data_size(client))
644 ipc_client_log(client, "nv_data_check: wrong nv_data.bin size");
645 nv_data_backup_restore(client);
648 if (stat(nv_data_md5_path(client), &nv_stat) < 0)
650 ipc_client_log(client, "nv_data_check: nv_data.bin.md5 missing");
651 nv_data_backup_restore(client);
654 if (stat(nv_data_bak_path(client), &nv_stat) < 0 || stat(nv_data_md5_bak_path(client), &nv_stat) < 0)
656 ipc_client_log(client, "nv_data_check: .nv_data.bak or .nv_data.bak.md5 missing");
657 nv_data_backup_create(client);
660 nv_state_fd = open(nv_state_path(client), O_RDONLY);
662 if (nv_state_fd < 0 || fstat(nv_state_fd, &nv_stat) < 0)
664 ipc_client_log(client, "nv_data_check: .nv_state missing");
665 nv_data_backup_restore(client);
668 rc = read(nv_state_fd, &nv_state, sizeof(nv_state));
671 ipc_client_log(client, "nv_data_check: couldn't read state of NV item from file");
679 ipc_client_log(client, "nv_data_check: bad nv_state");
680 nv_data_backup_restore(client);
683 ipc_client_log(client, "nv_data_check: everything should be alright");
684 ipc_client_log(client, "nv_data_check: exit");
689 int nv_data_md5_check(struct ipc_client *client)
692 uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
693 char *nv_data_md5_hash_string = NULL;
694 char *nv_data_md5_hash_read = NULL;
695 void *nv_data_p = NULL;
700 ipc_client_log(client, "nv_data_md5_check: enter");
702 nv_data_md5_hash_string = malloc(MD5_STRING_SIZE);
703 nv_data_md5_hash_read = malloc(MD5_STRING_SIZE);
705 memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
706 memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);
708 nv_data_p = file_data_read(nv_data_path(client),
709 nv_data_size(client), nv_data_chunk_size(client));
712 nv_data_md5_compute(data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
714 md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);
718 fd = open(nv_data_md5_path(client), O_RDONLY);
720 /* Read the md5 stored in the file. */
721 rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
724 ipc_client_log(client, "nv_data_md5_check: Can't read md5 hash from file");
728 /* Add 0x0 to end the string: not sure this is part of the file. */
729 nv_data_md5_hash_read[MD5_STRING_SIZE - 1] = '\0';
731 ipc_client_log(client, "nv_data_md5_check: computed MD5: %s read MD5: %s",
732 nv_data_md5_hash_string, nv_data_md5_hash_read);
734 if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
736 ipc_client_log(client, "nv_data_md5_check: MD5 hash mismatch");
737 nv_data_backup_restore(client);
740 if (nv_data_md5_hash_string != NULL)
741 free(nv_data_md5_hash_string);
742 if (nv_data_md5_hash_read != NULL)
743 free(nv_data_md5_hash_read);
745 ipc_client_log(client, "nv_data_md5_check: exit");
750 int nv_data_read(struct ipc_client *client, int offset, int length, char *buf)
755 ipc_client_log(client, "nv_data_read: enter");
757 if (offset < 0 || length <= 0) {
758 ipc_client_log(client, "nv_data_read: offset < 0 or length <= 0");
763 ipc_client_log(client, "nv_data_read: provided output buf is NULL");
767 if (nv_data_check(client) < 0)
770 fd = open(nv_data_path(client), O_RDONLY);
772 ipc_client_log(client, "nv_data_read: nv_data file fd is negative");
776 lseek(fd, offset, SEEK_SET);
778 rc = read(fd, buf, length);
780 ipc_client_log(client, "nv_data_read: read less than what we expected");
784 ipc_client_log(client, "nv_data_read: exit");
789 int nv_data_write(struct ipc_client *client, int offset, int length, char *buf)
794 ipc_client_log(client, "nv_data_write: enter");
796 if (offset < 0 || length <= 0) {
797 ipc_client_log(client, "nv_data_write: offset or length <= 0");
802 ipc_client_log(client, "nv_data_write: provided input buf is NULL");
806 if (nv_data_check(client) < 0)
809 fd = open(nv_data_path(client), O_WRONLY);
811 ipc_client_log(client, "nv_data_write: nv_data file fd is negative");
815 lseek(fd, offset, SEEK_SET);
817 rc = write(fd, buf, length);
822 ipc_client_log(client, "nv_data_write: wrote less (%d) than what we expected (%d), error: %s, restoring backup", rc, length, strerror(errno));
823 nv_data_backup_restore(client);
827 ipc_client_log(client, "nv_data_write: writing new md5sum");
828 nv_data_md5_generate(client);
830 ipc_client_log(client, "nv_data_write: exit");
835 void ipc_rfs_send_io_confirm_for_nv_read_item(struct ipc_client *client,
836 struct ipc_message_info *info)
838 struct ipc_rfs_io *rfs_io = (struct ipc_rfs_io *) info->data;
839 struct ipc_rfs_io_confirm *rfs_io_conf;
845 ipc_client_log(client, "ERROR: Request message is invalid: aseq = %i", info->aseq);
849 rfs_io_conf = malloc(rfs_io->length + sizeof(struct ipc_rfs_io_confirm));
850 memset(rfs_io_conf, 0, rfs_io->length + sizeof(struct ipc_rfs_io_confirm));
851 rfs_data = rfs_io_conf + sizeof(struct ipc_rfs_io_confirm);
853 ipc_client_log(client, "Asked to read 0x%x bytes at offset 0x%x", rfs_io->length, rfs_io->offset);
854 rc = nv_data_read(client, rfs_io->offset, rfs_io->length, rfs_data);
857 ipc_client_log(client, "Read rfs_data dump:");
858 ipc_client_hex_dump(client, rfs_data, rfs_io->length);
861 ipc_client_log(client, "Preparing RFS IO Confirm message (rc is %d)", rc);
862 rfs_io_conf->confirm = rc < 0 ? 0 : 1;
863 rfs_io_conf->offset = rfs_io->offset;
864 rfs_io_conf->length = rfs_io->length;
866 ipc_client_send(client, IPC_RFS_NV_READ_ITEM, 0, (unsigned char *) rfs_io_conf,
867 rfs_io->length + sizeof(struct ipc_rfs_io_confirm), info->aseq);
871 void ipc_rfs_send_io_confirm_for_nv_write_item(struct ipc_client *client,
872 struct ipc_message_info *info)
874 struct ipc_rfs_io *rfs_io = (struct ipc_rfs_io *) info->data;
875 struct ipc_rfs_io_confirm *rfs_io_conf;
881 ipc_client_log(client, "ERROR: Request message is invalid: aseq = %i", info->aseq);
885 rfs_data = info->data + sizeof(struct ipc_rfs_io);
888 ipc_client_log(client, "Write rfs_data dump:");
889 ipc_client_hex_dump(client, rfs_data, rfs_io->length);
892 ipc_client_log(client, "Asked to write 0x%x bytes at offset 0x%x", rfs_io->length, rfs_io->offset);
893 rc = nv_data_write(client, rfs_io->offset, rfs_io->length, rfs_data);
895 ipc_client_log(client, "Sending RFS IO Confirm message (rc is %d)", rc);
896 rfs_io_conf = (struct ipc_rfs_io_confirm*) malloc(sizeof(struct ipc_rfs_io_confirm));
897 rfs_io_conf->confirm = rc < 0 ? 0 : 1;
898 rfs_io_conf->offset = rfs_io->offset;
899 rfs_io_conf->length = rfs_io->length;
901 ipc_client_send(client, IPC_RFS_NV_WRITE_ITEM, 0, (unsigned char *) rfs_io_conf,
902 sizeof(struct ipc_rfs_io_confirm), info->aseq);
906 // vim:ts=4:sw=4:expandtab