Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Net handling #14

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions artnet/artnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ uint16_t LOW_BYTE = 0x00FF;
uint16_t HIGH_BYTE = 0xFF00;

void copy_apr_to_node_entry(artnet_node_entry e, artnet_reply_t *reply);
int find_nodes_from_uni(node_list_t *nl, uint8_t uni, SI *ips, int size);
int find_nodes_from_uni(node_list_t *nl, uint16_t uni, SI *ips, int size);

/*
* Creates a new ArtNet node.
Expand Down Expand Up @@ -739,7 +739,7 @@ int artnet_send_address(artnet_node vn,
const char *longName,
uint8_t inAddr[ARTNET_MAX_PORTS],
uint8_t outAddr[ARTNET_MAX_PORTS],
uint8_t subAddr, artnet_port_command_t cmd) {
uint8_t net, uint8_t subAddr, artnet_port_command_t cmd) {
node n = (node) vn;
artnet_packet_t p;
node_entry_private_t *ent = find_private_entry(n,e);
Expand All @@ -763,14 +763,14 @@ int artnet_send_address(artnet_node vn,
p.data.addr.opCode = htols(ARTNET_ADDRESS);
p.data.addr.verH = 0;
p.data.addr.ver = ARTNET_VERSION;
p.data.addr.filler1 = 0;
p.data.addr.filler2 = 0;
strncpy((char*) &p.data.addr.shortname, shortName, ARTNET_SHORT_NAME_LENGTH);
strncpy((char*) &p.data.addr.longname, longName, ARTNET_LONG_NAME_LENGTH);

memcpy(&p.data.addr.swin, inAddr, ARTNET_MAX_PORTS);
memcpy(&p.data.addr.swout, outAddr, ARTNET_MAX_PORTS);

p.data.addr.net = net;
p.data.addr.subnet = subAddr;
p.data.addr.swvideo = 0x00;
p.data.addr.command = cmd;
Expand Down Expand Up @@ -1128,27 +1128,30 @@ int artnet_set_node_type(artnet_node vn, artnet_node_type type) {
* Note that changing the subnet address will cause the universe addresses of all ports to change.
*
* @param vn the artnet_node
* @param net new net address
* @param subnet new subnet address
*/
int artnet_set_subnet_addr(artnet_node vn, uint8_t subnet) {
int artnet_set_net_subnet_addr(artnet_node vn, uint8_t net, uint8_t subnet) {
node n = (node) vn;
int i, ret;

check_nullnode(vn);

n->state.default_net = net;
n->state.default_subnet = subnet;

// if not under network control, and the subnet is different from the current one
if (!n->state.subnet_net_ctl && subnet != n->state.subnet) {
if (!n->state.subnet_net_ctl && (subnet != n->state.subnet || net != n->state.net)) {
n->state.net = net;
n->state.subnet = subnet;

// redo the addresses for each port
for (i =0; i < ARTNET_MAX_PORTS; i++) {
n->ports.in[i].port_addr = ((n->state.subnet & LOW_NIBBLE) << 4) | (n->ports.in[i].port_addr & LOW_NIBBLE);
n->ports.in[i].port_addr = (net << 8) | ((n->state.subnet & LOW_NIBBLE) << 4) | (n->ports.in[i].port_addr & LOW_NIBBLE);
// reset dmx sequence number
n->ports.in[i].seq = 0;

n->ports.out[i].port_addr = ((n->state.subnet & LOW_NIBBLE) << 4) | (n->ports.out[i].port_addr & LOW_NIBBLE);
n->ports.out[i].port_addr = (net << 8) | ((n->state.subnet & LOW_NIBBLE) << 4) | (n->ports.out[i].port_addr & LOW_NIBBLE);
}

if (n->state.mode == ARTNET_ON) {
Expand Down Expand Up @@ -1290,7 +1293,7 @@ int artnet_set_port_addr(artnet_node vn,
// if not under network control and address is changing
if (!port->net_ctl &&
(changed || (addr & LOW_NIBBLE) != (port->addr & LOW_NIBBLE))) {
port->addr = ((n->state.subnet & LOW_NIBBLE) << 4) | (addr & LOW_NIBBLE);
port->addr = n->state.net << 8 | ((n->state.subnet & LOW_NIBBLE) << 4) | (addr & LOW_NIBBLE);

// reset seq if input port
if (dir == ARTNET_INPUT_PORT)
Expand Down Expand Up @@ -1345,6 +1348,7 @@ int artnet_get_config(artnet_node vn, artnet_node_config_t *config) {

strncpy(config->short_name, n->state.short_name, ARTNET_SHORT_NAME_LENGTH);
strncpy(config->long_name, n->state.long_name, ARTNET_LONG_NAME_LENGTH);
config->net = n->state.net;
config->subnet = n->state.subnet;

for (i = 0; i < ARTNET_MAX_PORTS; i++) {
Expand Down Expand Up @@ -1561,15 +1565,17 @@ node_entry_private_t *find_entry_from_ip(node_list_t *nl, SI ip) {
* @param size size of ips
* @return number of nodes matched
*/
int find_nodes_from_uni(node_list_t *nl, uint8_t uni, SI *ips, int size) {
int find_nodes_from_uni(node_list_t *nl, uint16_t uni, SI *ips, int size) {
node_entry_private_t *tmp;
int count = 0;
int i,j = 0;
uint16_t outputUniverse = 0;

for (tmp = nl->first; tmp; tmp = tmp->next) {
int added = FALSE;
for (i =0; i < tmp->pub.numbports; i++) {
if (tmp->pub.swout[i] == uni && ips) {
outputUniverse = (tmp->pub.swout[i] & LOW_NIBBLE) | tmp->pub.sub << 4 | tmp->pub.net << 8;
if (outputUniverse == uni && ips) {
if (j < size && !added) {
ips[j++] = tmp->ip;
added = TRUE;
Expand All @@ -1590,7 +1596,8 @@ void copy_apr_to_node_entry(artnet_node_entry e, artnet_reply_t *reply) {
// the ip is network byte ordered
memcpy(&e->ip, &reply->ip, 4);
e->ver = bytes_to_short(reply->verH, reply->ver);
e->sub = bytes_to_short(reply->subH, reply->sub);
e->net = reply->net;
e->sub = reply->sub;
e->oem = bytes_to_short(reply->oemH, reply->oem);
e->ubea = reply->ubea;
memcpy(&e->etsaman, &reply->etsaman, 2);
Expand Down
7 changes: 5 additions & 2 deletions artnet/artnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ typedef enum {
typedef struct artnet_node_entry_s {
uint8_t ip[ARTNET_IP_SIZE]; /**< The IP address, Network byte ordered*/
int16_t ver; /**< The firmware version */
int16_t sub; /**< The subnet address */
int8_t net; /**< The net address */
int8_t sub; /**< The subnet address */
int16_t oem; /**< The OEM value */
uint8_t ubea; /**< The UBEA version */
uint8_t status;
Expand All @@ -198,6 +199,7 @@ typedef artnet_node_entry_t *artnet_node_entry;
typedef struct {
char short_name[ARTNET_SHORT_NAME_LENGTH];
char long_name[ARTNET_LONG_NAME_LENGTH];
uint8_t net;
uint8_t subnet;
uint8_t in_ports[ARTNET_MAX_PORTS];
uint8_t out_ports[ARTNET_MAX_PORTS];
Expand Down Expand Up @@ -272,6 +274,7 @@ EXTERN int artnet_send_address(artnet_node n,
const char *longName,
uint8_t inAddr[ARTNET_MAX_PORTS],
uint8_t outAddr[ARTNET_MAX_PORTS],
uint8_t net,
uint8_t subAddr,
artnet_port_command_t cmd);
EXTERN int artnet_send_input(artnet_node n,
Expand Down Expand Up @@ -326,7 +329,7 @@ EXTERN int artnet_set_port_addr(artnet_node n,
int id,
artnet_port_dir_t dir,
uint8_t addr);
EXTERN int artnet_set_subnet_addr(artnet_node n, uint8_t subnet);
EXTERN int artnet_set_net_subnet_addr(artnet_node n, uint8_t net, uint8_t subnet);
EXTERN int artnet_get_universe_addr(artnet_node n,
int id,
artnet_port_dir_t dir);
Expand Down
8 changes: 4 additions & 4 deletions artnet/packets.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ struct artnet_reply_s {
uint16_t port;
uint8_t verH;
uint8_t ver;
uint8_t subH;
uint8_t net;
uint8_t sub;
uint8_t oemH;
uint8_t oem;
Expand Down Expand Up @@ -195,7 +195,7 @@ struct artnet_address_s {
uint16_t opCode;
uint8_t verH;
uint8_t ver;
uint8_t filler1;
uint8_t net;
uint8_t filler2;
uint8_t shortname[ARTNET_SHORT_NAME_LENGTH];
uint8_t longname[ARTNET_LONG_NAME_LENGTH];
Expand Down Expand Up @@ -254,7 +254,7 @@ struct artnet_todrequest_s {
uint8_t spare5;
uint8_t spare6;
uint8_t spare7;
uint8_t spare8;
uint8_t net;
uint8_t command;
uint8_t adCount;
uint8_t address[ARTNET_MAX_RDM_ADCOUNT];
Expand All @@ -278,7 +278,7 @@ struct artnet_toddata_s {
uint8_t spare5;
uint8_t spare6;
uint8_t spare7;
uint8_t spare8;
uint8_t net;
uint8_t cmdRes;
uint8_t address;
uint8_t uidTotalHi;
Expand Down
4 changes: 3 additions & 1 deletion artnet/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ typedef struct {

// first a generic port
typedef struct {
uint8_t addr; // the port address
uint16_t addr; // the port address
uint8_t default_addr; // the address set by the hardware
uint8_t net_ctl; // if the port address is under network control
uint8_t status; // status of the port
Expand Down Expand Up @@ -417,6 +417,7 @@ typedef struct {
SI ip_addr;
SI bcast_addr;
uint8_t hw_addr[ARTNET_MAC_SIZE];
uint8_t default_net;
uint8_t default_subnet;
uint8_t subnet_net_ctl;
int send_apr_on_change;
Expand All @@ -425,6 +426,7 @@ typedef struct {
char short_name[ARTNET_SHORT_NAME_LENGTH];
char long_name[ARTNET_LONG_NAME_LENGTH];
char report[ARTNET_REPORT_LENGTH];
uint8_t net;
uint8_t subnet;
uint8_t oem_hi;
uint8_t oem_lo;
Expand Down
26 changes: 14 additions & 12 deletions artnet/receive.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "private.h"

uint8_t _make_addr(uint8_t subnet, uint8_t addr);
uint16_t _make_addr(uint8_t net, uint8_t subnet, uint8_t addr);
void check_merge_timeouts(node n, int port);
void merge(node n, int port, int length, uint8_t *latest);

Expand Down Expand Up @@ -238,7 +238,7 @@ void handle_dmx(node n, artnet_packet p) {
*
*/
int handle_address(node n, artnet_packet p) {
int i, old_subnet;
int i, old_subnet, old_net;
int addr[ARTNET_MAX_PORTS];
int ret;

Expand Down Expand Up @@ -269,9 +269,11 @@ int handle_address(node n, artnet_packet p) {
}

// program subnet
old_net = p->data.addr.net;
old_subnet = p->data.addr.subnet;
if (p->data.addr.subnet == PROGRAM_DEFAULTS) {
// reset to defaults
n->state.net = n->state.default_net;
n->state.subnet = n->state.default_subnet;
n->state.subnet_net_ctl = FALSE;

Expand All @@ -281,11 +283,11 @@ int handle_address(node n, artnet_packet p) {
}

// check if subnet has actually changed
if (old_subnet != n->state.subnet) {
if (old_net != n->state.net || old_subnet != n->state.subnet) {
// if it does we need to change all port addresses
for(i=0; i< ARTNET_MAX_PORTS; i++) {
n->ports.in[i].port_addr = _make_addr(n->state.subnet, n->ports.in[i].port_addr);
n->ports.out[i].port_addr = _make_addr(n->state.subnet, n->ports.out[i].port_addr);
n->ports.in[i].port_addr = _make_addr(n->state.net, n->state.subnet, (uint8_t)n->ports.in[i].port_addr);
n->ports.out[i].port_addr = _make_addr(n->state.net, n->state.subnet, (uint8_t)n->ports.out[i].port_addr);
}
}

Expand All @@ -295,11 +297,11 @@ int handle_address(node n, artnet_packet p) {
continue;
} else if (p->data.addr.swin[i] == PROGRAM_DEFAULTS) {
// reset to defaults
n->ports.in[i].port_addr = _make_addr(n->state.subnet, n->ports.in[i].port_default_addr);
n->ports.in[i].port_addr = _make_addr(n->state.net, n->state.subnet, n->ports.in[i].port_default_addr);
n->ports.in[i].port_net_ctl = FALSE;

} else if ( p->data.addr.swin[i] & PROGRAM_CHANGE_MASK) {
n->ports.in[i].port_addr = _make_addr(n->state.subnet, p->data.addr.swin[i]);
n->ports.in[i].port_addr = _make_addr(n->state.net, n->state.subnet, p->data.addr.swin[i]);
n->ports.in[i].port_net_ctl = TRUE;
}
}
Expand All @@ -310,11 +312,11 @@ int handle_address(node n, artnet_packet p) {
continue;
} else if (p->data.addr.swout[i] == PROGRAM_DEFAULTS) {
// reset to defaults
n->ports.out[i].port_addr = _make_addr(n->state.subnet, n->ports.out[i].port_default_addr);
n->ports.out[i].port_addr = _make_addr(n->state.net, n->state.subnet, n->ports.out[i].port_default_addr);
n->ports.out[i].port_net_ctl = FALSE;
n->ports.out[i].port_enabled = TRUE;
} else if ( p->data.addr.swout[i] & PROGRAM_CHANGE_MASK) {
n->ports.out[i].port_addr = _make_addr(n->state.subnet, p->data.addr.swout[i]);
n->ports.out[i].port_addr = _make_addr(n->state.net, n->state.subnet, p->data.addr.swout[i]);
n->ports.in[i].port_net_ctl = TRUE;
n->ports.out[i].port_enabled = TRUE;
}
Expand Down Expand Up @@ -854,10 +856,10 @@ int16_t get_type(artnet_packet p) {


/*
* takes a subnet and an address and creates the universe address
* takes a net, subnet and an address and creates the universe address
*/
uint8_t _make_addr(uint8_t subnet, uint8_t addr) {
return ((subnet & LOW_NIBBLE) << 4) | (addr & LOW_NIBBLE);
uint16_t _make_addr(uint8_t net, uint8_t subnet, uint8_t addr) {
return (net << 8 ) | ((subnet & LOW_NIBBLE) << 4) | (addr & LOW_NIBBLE);
}


Expand Down
11 changes: 6 additions & 5 deletions artnet/transmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ int artnet_tx_tod_request(node n) {
todreq.data.todreq.adCount = 0;

// include all enabled ports
todreq.data.todreq.net = n->state.net;
for (i=0; i < ARTNET_MAX_PORTS; i++) {
if (n->ports.out[i].port_enabled) {
todreq.data.todreq.address[todreq.data.todreq.adCount++] = n->ports.out[i].port_addr;
todreq.data.todreq.address[todreq.data.todreq.adCount++] = n->ports.out[i].port_addr & LOW_BYTE;
}
}

Expand Down Expand Up @@ -155,7 +156,7 @@ int artnet_tx_tod_data(node n, int id) {
// codes aren't given. The windows drivers don't have these either....
tod.data.toddata.cmdRes = ARTNET_TOD_FULL;

tod.data.toddata.address = n->ports.out[id].port_addr;
tod.data.toddata.address = n->ports.out[id].port_addr & LOW_BYTE;
tod.data.toddata.uidTotalHi = short_get_high_byte(n->ports.out[id].port_tod.length);
tod.data.toddata.uidTotal = short_get_low_byte(n->ports.out[id].port_tod.length);

Expand Down Expand Up @@ -368,7 +369,7 @@ int artnet_tx_build_art_poll_reply(node n) {
ar->port = htols(ARTNET_PORT);
ar->verH = 0;
ar->ver = 0;
ar->subH = 0;
ar->net = n->state.net;
ar->sub = n->state.subnet;
ar->oemH = n->state.oem_hi;
ar->oem = n->state.oem_lo;
Expand Down Expand Up @@ -404,8 +405,8 @@ int artnet_tx_build_art_poll_reply(node n) {
ar->porttypes[i] = n->ports.types[i];
ar->goodinput[i] = n->ports.in[i].port_status;
ar->goodoutput[i] = n->ports.out[i].port_status;
ar->swin[i] = n->ports.in[i].port_addr;
ar->swout[i] = n->ports.out[i].port_addr;
ar->swin[i] = n->ports.in[i].port_addr & LOW_NIBBLE;
ar->swout[i] = n->ports.out[i].port_addr & LOW_NIBBLE;
}

ar->swvideo = 0;
Expand Down