1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <ctype.h>
18 #include <errno.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/mount.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "cutils/misc.h"
31 #include "cutils/properties.h"
32 #include "edify/expr.h"
33 #include "mincrypt/sha.h"
34 #include "minzip/DirUtil.h"
35 #include "mtdutils/mounts.h"
36 #include "mtdutils/mtdutils.h"
37
38
39 /* ioctl commands for /dev/dpram_recovery */
40 #define IOCTL_MODEM_FW_UPDATE _IO('D',0x1)
41 #define IOCTL_MODEM_CHK_STAT _IO('D',0x2)
42 #define IOCTL_MODEM_PWROFF _IO('D',0x3)
43
44 /* modem status during update */
45 struct stat_info {
46 int pct;
47 char msg[0x100];
48 };
49
50 /* buffer type for modem delta */
51 struct dpram_firmware {
52 char *firmware;
53 int size;
54 int is_delta;
55 };
56
UpdateModemFn(const char * name,State * state,int argc,Expr * argv[])57 Value* UpdateModemFn(const char* name, State* state,
58 int argc, Expr* argv[]) {
59
60 struct dpram_firmware fw;
61 struct stat_info st;
62 int ofd = -1;
63 int err = -1;
64 int prev_pct = -1;
65
66 if (argc != 1)
67 return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc);
68
69 Value* radio;
70 if (ReadValueArgs(state, argv, 1, &radio) != 0) {
71 return NULL;
72 }
73 if (radio->type != VAL_BLOB) {
74 ErrorAbort(state, "argument to %s() has wrong type", name);
75 FreeValue(radio);
76 return NULL;
77 }
78
79 if (radio->size <= 0) {
80 fprintf(stderr, "%s(): no file contents received", name);
81 return StringValue(strdup(""));
82 }
83
84 printf("UpdateModemFn with %d bytes\n", radio->size);
85
86 /* open modem device */
87 ofd = open("/dev/modem_ctl", O_RDWR);
88
89 if (ofd < 0) {
90 printf("Unable to open modem device (%s)\n", strerror(errno));
91 goto out;
92 }
93
94 /* initiate firmware update */
95 fw.firmware = radio->data;
96 fw.size = radio->size;
97 fw.is_delta = 0;
98 err = ioctl(ofd, IOCTL_MODEM_FW_UPDATE, &fw);
99
100 if (err < 0) {
101 printf("ioctl failed with %d\n", err);
102 goto out;
103 }
104
105 do {
106 err = ioctl(ofd, IOCTL_MODEM_CHK_STAT, &st);
107 if (prev_pct != st.pct) {
108 /* use st.pct to update UI */
109 printf(" %3d \%\n", st.pct);
110 prev_pct = st.pct;
111 }
112
113 if (err < 0) {
114 /* Aborted if an error occurrs during update */
115 printf("Update error %d\n", err);
116 printf("Error msg : %s\n", st.msg);
117
118 ioctl(ofd, IOCTL_MODEM_PWROFF, NULL);
119 goto out;
120 }
121 } while (err);
122
123 printf("Firmware Update is Successful!\n");
124
125 out:
126 FreeValue(radio);
127 if (ofd >= 0)
128 close(ofd);
129
130 return StringValue(strdup(err == 0 ? "t" : ""));
131 }
132
Register_librecovery_updater_crespo4g()133 void Register_librecovery_updater_crespo4g() {
134 printf("Register_librecovery_updater_crespo4g is called\n");
135 RegisterFunction("samsung.update_modem", UpdateModemFn);
136 }
137