1#!/usr/bin/env python
2
3import os
4
5# TODO: openbmc/openbmc#2994 remove python 2 support
6try:  # python 2
7    import gobject
8except ImportError:  # python 3
9    from gi.repository import GObject as gobject
10import dbus
11import dbus.service
12import dbus.mainloop.glib
13import subprocess
14from obmc.dbuslib.bindings import get_dbus
15
16
17FLASH_DOWNLOAD_PATH = "/tmp"
18DBUS_NAME = "org.openbmc.managers.Download"
19OBJ_NAME = "/org/openbmc/managers/Download"
20TFTP_PORT = 69
21
22
23class DownloadManagerObject(dbus.service.Object):
24    def __init__(self, bus, name):
25        dbus.service.Object.__init__(self, bus, name)
26        bus.add_signal_receiver(
27            self.DownloadHandler,
28            dbus_interface="org.openbmc.Flash",
29            signal_name="Download",
30            path_keyword="path",
31        )
32        bus.add_signal_receiver(
33            self.TftpDownloadHandler,
34            signal_name="TftpDownload",
35            path_keyword="path",
36        )
37
38    @dbus.service.signal(DBUS_NAME, signature="ss")
39    def DownloadComplete(self, outfile, filename):
40        print("Download Complete: " + outfile)
41        return outfile
42
43    @dbus.service.signal(DBUS_NAME, signature="s")
44    def DownloadError(self, filename):
45        pass
46
47    def TftpDownloadHandler(self, ip, filename, path=None):
48        try:
49            filename = str(filename)
50            print("Downloading: " + filename + " from " + ip)
51            outfile = FLASH_DOWNLOAD_PATH + "/" + os.path.basename(filename)
52            rc = subprocess.call(
53                ["tftp", "-l", outfile, "-r", filename, "-g", ip]
54            )
55            if rc == 0:
56                self.DownloadComplete(outfile, filename)
57            else:
58                self.DownloadError(filename)
59
60        except Exception as e:
61            print("ERROR DownloadManager: " + str(e))
62            self.DownloadError(filename)
63
64    # TODO: this needs to be deprecated.
65    # Shouldn't call flash interface from here
66    def DownloadHandler(self, url, filename, path=None):
67        try:
68            filename = str(filename)
69            print("Downloading: " + filename + " from " + url)
70            outfile = FLASH_DOWNLOAD_PATH + "/" + os.path.basename(filename)
71            subprocess.call(["tftp", "-l", outfile, "-r", filename, "-g", url])
72            obj = bus.get_object("org.openbmc.control.Flash", path)
73            intf = dbus.Interface(obj, "org.openbmc.Flash")
74            intf.update(outfile)
75
76        except Exception as e:
77            print("ERROR DownloadManager: " + str(e))
78            obj = bus.get_object("org.openbmc.control.Flash", path)
79            intf = dbus.Interface(obj, "org.openbmc.Flash")
80            intf.error("Download Error: " + filename)
81
82
83if __name__ == "__main__":
84    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
85    bus = get_dbus()
86    obj = DownloadManagerObject(bus, OBJ_NAME)
87    mainloop = gobject.MainLoop()
88    name = dbus.service.BusName(DBUS_NAME, bus)
89
90    print("Running Download Manager")
91    mainloop.run()
92
93# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
94