Home | History | Annotate | Download | only in recovery
      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