summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/network.cpp
blob: 5953031133eef5c5536b26d65fd4f381f13d8cfa (plain) (blame)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// license:BSD-3-Clause
// copyright-holders:Carl
/***************************************************************************

    network.cpp

    Core network functions and definitions.

***************************************************************************/

#include "emu.h"
#include "network.h"

#include "config.h"
#include "dinetwork.h"

#include "xmlfile.h"

#include <cctype>

//**************************************************************************
//  NETWORK MANAGER
//**************************************************************************

//-------------------------------------------------
//  network_manager - constructor
//-------------------------------------------------

network_manager::network_manager(running_machine &machine)
	: m_machine(machine)
{
	machine.configuration().config_register(
			"network",
			configuration_manager::load_delegate(&network_manager::config_load, this),
			configuration_manager::save_delegate(&network_manager::config_save, this));
}

//-------------------------------------------------
//  config_load - read and apply data from the
//  configuration file
//-------------------------------------------------

void network_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
	if ((cfg_type == config_type::SYSTEM) && parentnode)
	{
		for (util::xml::data_node const *node = parentnode->get_child("device"); node; node = node->get_next_sibling("device"))
		{
			const char *tag = node->get_attribute_string("tag", nullptr);

			if ((tag != nullptr) && (tag[0] != '\0'))
			{
				for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
				{
					if (!strcmp(tag, network.device().tag())) {
						int interface = node->get_attribute_int("interface", 0);
						network.set_interface(interface);
						const char *mac_addr = node->get_attribute_string("mac", nullptr);
						if (mac_addr != nullptr && strlen(mac_addr) == 17) {
							uint8_t mac[6];
							unsigned int mac_num[6];
							sscanf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", &mac_num[0], &mac_num[1], &mac_num[2], &mac_num[3], &mac_num[4], &mac_num[5]);
							for (int i = 0; i<6; i++) mac[i] = mac_num[i];
							network.set_mac(mac);
						}

					}
				}
			}
		}
	}
}
//-------------------------------------------------
//  config_save - save data to the configuration
//  file
//-------------------------------------------------

void network_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
	// only save about system-specific data
	if (cfg_type == config_type::SYSTEM)
	{
		for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
		{
			util::xml::data_node *const node = parentnode->add_child("device", nullptr);
			if (node)
			{
				node->set_attribute("tag", network.device().tag());
				node->set_attribute_int("interface", network.get_interface());
				const std::array<u8, 6> &mac = network.get_mac();
				const std::string mac_addr = util::string_format(
						"%02x:%02x:%02x:%02x:%02x:%02x",
						mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
				node->set_attribute("mac", mac_addr.c_str());
			}
		}
	}
}