• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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