blob: ca71e61ffc43f982d0674226a606e5569c49b970 [file] [log] [blame]
# Copyright (C) 2009 The Android Open Source Project
# Copyright (c) 2011, The Linux Foundation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Emit commands needed for QCOM devices during OTA installation
(installing the radio image)."""
import common
import re
def LoadFilesMap(zip, type=None):
try:
data = zip.read("RADIO/filesmap")
except KeyError:
print "Warning: could not find RADIO/filesmap in %s." % zip
data = ""
d = {}
for line in data.split("\n"):
line = line.strip()
if not line or line.startswith("#"): continue
pieces = line.split()
if not (len(pieces) == 2):
raise ValueError("malformed filesmap line: \"%s\"" % (line,))
d[pieces[0]] = pieces[1]
return d
def GetRadioFiles(z):
out = {}
for info in z.infolist():
if info.filename.startswith("RADIO/") and (info.filename.__len__() > len("RADIO/")):
fn = "RADIO/" + info.filename[6:]
out[fn] = fn
return out
def FullOTA_Assertions(info):
#TODO: Implement device specific asserstions.
return
def IncrementalOTA_Assertions(info):
#TODO: Implement device specific asserstions.
return
def InstallRawImage(image_data, api_version, input_zip, fn, info, filesmap):
#fn is in RADIO/* format. Extracting just file name.
filename = fn[6:]
if api_version >= 3:
if filename not in filesmap:
return
info.script.AppendExtra('package_extract_file("%s", "%s");' % (filename,filesmap[filename]))
common.ZipWriteStr(info.output_zip, filename, image_data)
return
else:
print "warning raido-update: no support for api_version less than 3."
def FULLOTA_InstallEnd_MMC(info):
files = GetRadioFiles(info.input_zip)
if files == {}:
print "warning radio-update: no radio image in input target_files; not flashing radio"
return
info.script.UnmountAll()
info.script.Print("Writing radio image...")
#Load filesmap file
filesmap = LoadFilesMap(info.input_zip, info.type)
if filesmap == {}:
print "warning radio-update: no or invalid filesmap file found. not flashing radio"
return
for f in files:
image_data = info.input_zip.read(f)
InstallRawImage(image_data, info.input_version, info.input_zip, f, info, filesmap)
return
def FULLOTA_InstallEnd_MTD(info):
print "warning radio-update: no implementation for radio upgrade for NAND devices"
return
def FullOTA_InstallEnd(info):
if info.type == 'MTD':
FULLOTA_InstallEnd_MTD(info)
if info.type == 'MMC':
FULLOTA_InstallEnd_MMC(info)
def WriteRadioFirmware(info, filename, target_radio_img, source_radio_img=None):
fn = filename[6:]
filesmap = LoadFilesMap(info.target_zip)
if filesmap == {}:
print "warning radio-update: no or invalid filesmap file found. Not flashing %s" % (fn)
return
tf = common.File(filename, target_radio_img)
if source_radio_img is None:
tf.AddToZip(info.output_zip)
info.script.Print("Writing radio...")
InstallRawImage(target_radio_img, info.target_version, info.target_zip, filename, info, filesmap)
else:
sf = common.File(filename, source_radio_img);
if tf.sha1 == sf.sha1:
print "%s image unchanged; skipping" % (fn)
else:
diff = common.Difference(tf, sf)
common.ComputeDifferences([diff])
_, _, d = diff.GetPatch()
if d is None or len(d) > tf.size * common.OPTIONS.patch_threshold:
# compute difference failed or the difference is bigger than
# target file - write the whole target file.
tf.AddToZip(info.output_zip)
info.script.Print("Writing radio ...")
InstallRawImage(target_radio_img, info.target_version, info.target_zip, filename, info, filesmap)
else:
PatchName = fn + ".p"
common.ZipWriteStr(info.output_zip, "patch/" + PatchName, d)
info.script.Print("Patching Radio...")
if info.type == 'MMC':
print "-------- EMMC device given -------"
radio_device = filesmap[fn]
info.script.ApplyPatch("%s:%s:%d:%s:%d:%s" %
("EMMC", radio_device, sf.size, sf.sha1, tf.size, tf.sha1),
"-", tf.size, tf.sha1, sf.sha1, "patch/" + PatchName)
else:
print "-------- MTD device given - not supported --------"
return
def IncrementalOTA_InstallEnd(info):
files = GetRadioFiles(info.target_zip)
if files == {}:
print "warning radio-update: no radio images in input target_files; not flashing radio"
return
filesmap = LoadFilesMap(info.target_zip)
if filesmap == {}:
print "warning radio-update: no or invalid filesmap file found. not flashing radio"
return
info.script.Print("Applying incremental radio image...")
for f in files:
try:
if f == "RADIO/filesmap": continue
target_radio_img = info.target_zip.read(f)
try:
source_radio_img = info.source_zip.read(f)
except KeyError:
print "source radio image = None"
source_radio_img = None
WriteRadioFirmware(info, f, target_radio_img, source_radio_img)
except KeyError:
print "no %s in target target_files; skipping install" % (f)
return