summaryrefslogtreecommitdiffstats
path: root/meta-netboot/README.renesas-gen3
blob: 225051af26385a9e903ef0ecebeabde9bb779e70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Below are the environment variables that can be set in the u-boot console to boot the Renesas Gen3 ULCB boards.

Adjust board type with the following identifiers:

* 'm3ulcb' for Renesas Gen3 Starter Kit Pro
* 'h3ulcb' for Renesas Gen3 Starter Kit Premium

################## Common options #####################
# these options are common to all configurations:

# choose board
setenv board m3ulcb
# or
setenv board h3ulcb

# kernel file
setenv set_bootkfile 'setenv bootkfile Image'
setenv bootkaddr 0x48080000

# dtb file
setenv set_bootdfile 'setenv bootdfile Image-r8a7796-${board}.dtb'
setenv bootdaddr 0x48000000

# initrd
setenv set_bootifile 'setenv bootifile initramfs-netboot-image-${board}.ext4.gz'
setenv bootiaddr 0x5C3F9520
setenv bootisize 3A6AB6

# kernel args
setenv bootargs_console 'console=ttySC0,115200 ignore_loglevel'
setenv bootargs_video 'vmalloc=384M video=HDMI-A-1:1920x1080-32@60'
setenv bootargs_extra 'rw rootfstype=ext4 rootwait rootdelay=2'

################ Boot on MMC (SDcard) #################

setenv bootargs_root 'root=/dev/mmcblk1p1'
setenv bootmmc '0:1'
setenv bootkload_sd 'ext4load mmc ${bootmmc} ${bootkaddr} boot/${bootkfile}'
setenv bootdload_sd 'ext4load mmc ${bootmmc} ${bootdaddr} boot/${bootdfile}'
setenv bootload_sd 'run set_bootkfile; run bootkload_sd; run set_bootdfile; run bootdload_sd'
setenv bootcmd 'setenv bootargs ${bootargs_console} ${bootargs_video} ${bootargs_root} ${bootargs_extra}; run bootload_sd; booti ${bootkaddr} - ${bootdaddr}'

################ Boot on MMC (SDcard) with initrd ######

setenv bootargs_root 'root=/dev/ram0 ramdisk_size=16384'
setenv bootmmc '0:1'
setenv bootkload_sd 'ext4load mmc ${bootmmc} ${bootkaddr} boot/${bootkfile}'
setenv bootdload_sd 'ext4load mmc ${bootmmc} ${bootdaddr} boot/${bootdfile}'
setenv bootiload_sd 'ext4load mmc ${bootmmc} ${bootiaddr} boot/${bootifile}'
setenv bootload_sd 'run set_bootkfile; run bootkload_sd; run set_bootdfile; run bootdload_sd; run set_bootifile; run bootiload_sd'

setenv bootcmd 'setenv bootargs ${bootargs_console} ${bootargs_video} ${bootargs_root} ${bootargs_extra}; run bootload_sd; booti ${bootkaddr} ${bootiaddr}:${bootisize} ${bootdaddr}'

################ Netboot through TFTP+NBD ##################
# replace <IP> addresses by appropriate addresses

setenv ipaddr '<board_IP>'
setenv serverip '<server_IP>'
setenv ethact ravb
setenv ethaddr DE:AD:C0:FF:EE:01

setenv bootargs_root 'root=/dev/ram0 ramdisk_size=16384 ip=dhcp'
setenv bootkload_net 'tftp ${bootkaddr} ${board}/${bootkfile}'
setenv bootdload_net 'tftp ${bootdaddr} ${board}/${bootdfile}'
setenv bootiload_net 'tftp ${bootiaddr} ${board}/${bootifile}'
setenv bootload_net 'run set_bootkfile; run bootkload_net; run set_bootdfile; run bootdload_net; run set_bootifile; run bootiload_net'

setenv bootcmd 'setenv bootargs ${bootargs_console} ${bootargs_video} ${bootargs_root} ${bootargs_extra} nbd.server=${serverip}; run bootload_net; booti ${bootkaddr} ${bootiaddr}:${bootisize} ${bootdaddr}'
String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (C) 2018-2020 Konsulko Group
 *
 * 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.
 */

#include <QDebug>
#include <QtQml/QQmlEngine>

#include "callmessage.h"
#include "eventmessage.h"
#include "responsemessage.h"
#include "messagefactory.h"
#include "messageengine.h"
#include "messageenginefactory.h"
#include "networkadapter.h"
#include "network.h"


Network::Network (QUrl &url, QQmlContext *context, QObject * parent) :
    QObject(parent)
{
    m_mloop = MessageEngineFactory::getInstance().getMessageEngine(url);
    m_adapters.append(new WifiAdapter(this, context, parent));

    QObject::connect(m_mloop.get(), &MessageEngine::connected, this, &Network::onConnected);
    QObject::connect(m_mloop.get(), &MessageEngine::disconnected, this, &Network::onDisconnected);
    QObject::connect(m_mloop.get(), &MessageEngine::messageReceived, this, &Network::onMessageReceived);

    m_adapters.append(new WiredAdapter(this, context, parent));
}

Network::~Network()
{
    while (!m_adapters.isEmpty())
        m_adapters.takeLast();
}

void Network::connect(QString service)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    parameter.insert("service", service);

    nmsg->createRequest("network-manager", "connect_service", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::disconnect(QString service)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    parameter.insert("service", service);

    nmsg->createRequest("network-manager", "disconnect_service", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::remove(QString service)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    parameter.insert("service", service);

    nmsg->createRequest("network-manager", "remove_service", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::power(bool on, QString type)
{
    if (on)
        enableTechnology(type);
    else
        disableTechnology(type);
}

void Network::input(int id, QString passphrase)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter, fields;

    parameter.insert("id", id);
    fields.insert("passphrase", passphrase);
    parameter.insert("fields", fields);

    nmsg->createRequest("network-manager", "agent_response", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::configureAddress(QString service, QVariantList paramlist)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter, type, properties;
    QJsonArray  values = QJsonArray::fromVariantList(paramlist);

    if (values.isEmpty() || values.count() < 4) {
        qWarning("Invalid addressing params");
        return;
    }

    properties.insert("method", values[0]);
    properties.insert("address", values[1]);
    properties.insert("netmask", values[2]);
    properties.insert("gateway", values[3]);
    type.insert("ipv4.configuration", properties);
    parameter.insert("properties", type);
    parameter.insert("service", service);

    nmsg->createRequest("network-manager", "set_property", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::configureNameServer(QString service, QVariantList paramlist)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter, properties;
    QJsonArray  values = QJsonArray::fromVariantList(paramlist);

    if (values.isEmpty() || values.count() < 2) {
        qWarning("Invalid nameserver params");
        return;
    }

    QStringList nslist = values[1].toString().split(' ');
    QJsonArray nameservers = QJsonArray::fromStringList(nslist);

    properties.insert("nameservers.configuration", nameservers);
    parameter.insert("properties", properties);
    parameter.insert("service", service);

    nmsg->createRequest("network-manager", "set_property", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::getServices()
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    nmsg->createRequest("network-manager", "services", parameter);
    m_mloop->sendMessage(std::move(msg));
}

AdapterIf* Network::findAdapter(QString type)
{
    QList<AdapterIf*>::iterator iter;
    for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter)
        if  ((*iter)->getType() == type)
            return (*iter);
    return nullptr;
}

void Network::updateServiceProperties(QJsonObject data)
{
    QString service = data.value("service").toString();
    QJsonObject properties = data.value("properties").toObject();
    QList<AdapterIf*>::iterator iter;
    for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter)
        (*iter)->updateProperties(service, properties);

}

bool Network::addService(QJsonObject service)
{
    QString id = service.value("service").toString();
    QJsonObject properties = service.value("properties").toObject();
    QList<AdapterIf*>::iterator iter;
    for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter)
        if ((*iter)->addService(id, properties))
            return true;

    return false;
}

void Network::removeService(QJsonObject service)
{
    QString id = service.value("service").toString();
    QList<AdapterIf*>::iterator iter;
    for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter)
        (*iter)->removeService(id);
}

void Network::addServices(QJsonArray services)
{
    for (auto service : services)
        addService(service.toObject());
}

void Network::scanServices(QString type)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    parameter.insert("technology", type);
    nmsg->createRequest("network-manager", "scan_services", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::disableTechnology(QString type)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    parameter.insert("technology", type);
    nmsg->createRequest("network-manager", "disable_technology", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::enableTechnology(QString type)
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    parameter.insert("technology", type);
    nmsg->createRequest("network-manager", "enable_technology", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::parseTechnologies(QJsonArray technologies)
{
    for (auto value : technologies) {
        QJsonObject technology = value.toObject();
        QJsonObject properties = technology.value("properties").toObject();
        QString type = properties.value("type").toString();

        AdapterIf* adapter = findAdapter(type);
        if (adapter)
            adapter->updateStatus(properties);
    }
}

void Network::getTechnologies()
{
    std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
    if (!msg)
        return;

    CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
    QJsonObject parameter;

    nmsg->createRequest("network-manager", "technologies", parameter);
    m_mloop->sendMessage(std::move(msg));
}

void Network::processEvent(std::shared_ptr<Message> msg)
{
    std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
    QString ename = emsg->eventName();
    QString eapi = emsg->eventApi();
    QJsonObject data = emsg->eventData();

    if (eapi != "network-manager")
        return;

    if (ename == "agent") {
        QJsonObject fields = data.value("fields").toObject();
        QJsonObject passphrase = fields.value("passphrase").toObject();
        QString type = passphrase.value("type").toString();
        QString reqmt = passphrase.value("requirement").toString();
        if (((type == "psk") || (type == "wep")) && (reqmt == "mandatory")) {
            int id = data.value("id").toInt();
            emit inputRequest(id);
        }
    } else if (ename == "services") {
        QJsonArray services = data.value("values").toArray();
        for (auto value : services) {
            QJsonObject service = value.toObject();
            QString action = service.value("action").toString();
            if (action == "changed") {
                addService(service);
            } else if (action == "removed") {
                 removeService(service);
            }
        }
    } else if (ename == "service_properties") {
        updateServiceProperties(data);
    } else if (ename == "technology_properties") {
        QJsonObject properties = data.value("properties").toObject();
        QString type = data.value("technology").toString();
        AdapterIf* adapter = findAdapter(type);
        if (adapter)
            adapter->updateStatus(properties);
    }
}

void Network::processReply(std::shared_ptr<Message> msg)
{
    std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
    QString verb = rmsg->requestVerb();
    QJsonObject data = rmsg->replyData();

    if (verb == "services") {
        addServices(data.value("values").toArray());
    } else if (verb == "technologies") {
        parseTechnologies(data.value("values").toArray());
    } else if (verb == "connect_service") {
        if (rmsg->replyStatus() == "failed" && rmsg->replyInfo().contains("invalid-key")) {
            emit invalidPassphrase(rmsg->requestParameters()["service"].toString());
        }
    }
}

void Network::onMessageReceived(std::shared_ptr<Message> msg)
{
    if (!msg)
        return;

    if (msg->isEvent())
        processEvent(msg);
    else if (msg->isReply())
        processReply(msg);
}

void Network::onConnected()
{
    QStringListIterator eventIterator(events);

    while (eventIterator.hasNext()) {
        std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
        if (!msg)
            return;

        CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
        QJsonObject parameter;
        parameter.insert("value", eventIterator.next());
        nmsg->createRequest("network-manager", "subscribe", parameter);
        m_mloop->sendMessage(std::move(msg));
    }

    getTechnologies();
}

void Network::onDisconnected()
{
    QStringListIterator eventIterator(events);

    while (eventIterator.hasNext()) {
        std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
        if (!msg)
            return;
        CallMessage *nmsg = static_cast<CallMessage*>(msg.get());
        QJsonObject parameter;
        parameter.insert("value", eventIterator.next());
        nmsg->createRequest("network-manager", "unsubscribe", parameter);
        m_mloop->sendMessage(std::move(msg));
    }

    getTechnologies();
}