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 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 133 void Register_librecovery_updater_crespo4g() { 134 printf("Register_librecovery_updater_crespo4g is called\n"); 135 RegisterFunction("samsung.update_modem", UpdateModemFn); 136 } 137