2 * Copyright 2013 IBM Corp.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 module.exports = function(RED) {
19 var dgram = require('dgram');
23 RED.nodes.createNode(this,n);
26 this.datatype = n.datatype;
27 this.iface = n.iface || null;
28 this.multicast = n.multicast;
31 var server = dgram.createSocket('udp4');
33 server.on("error", function (err) {
34 if ((err.code == "EACCES") && (node.port < 1024)) {
35 node.error("UDP access error, you may need root access for ports below 1024");
37 node.error("UDP error : "+err.code);
42 server.on('message', function (message, remote) {
44 if (node.datatype =="base64") {
45 msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port };
46 } else if (node.datatype =="utf8") {
47 msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port };
49 msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
54 server.on('listening', function () {
55 var address = server.address();
56 node.log('udp listener at ' + address.address + ":" + address.port);
57 if (node.multicast == "true") {
58 server.setBroadcast(true);
60 server.setMulticastTTL(128);
61 server.addMembership(node.group,node.iface);
62 node.log("udp multicast group "+node.group);
64 if (e.errno == "EINVAL") {
65 node.error("Bad Multicast Address");
66 } else if (e.errno == "ENODEV") {
67 node.error("Must be ip address of the required interface");
69 node.error("Error :"+e.errno);
75 node.on("close", function() {
78 node.log('udp listener stopped');
84 server.bind(node.port,node.iface);
86 RED.nodes.registerType("udp in",UDPin);
91 RED.nodes.createNode(this,n);
92 //this.group = n.group;
94 this.outport = n.outport||"";
95 this.base64 = n.base64;
97 this.iface = n.iface || null;
98 this.multicast = n.multicast;
101 var sock = dgram.createSocket('udp4'); // only use ipv4 for now
103 if (node.multicast != "false") {
104 if (node.outport == "") { node.outport = node.port; }
105 sock.bind(node.outport, function() { // have to bind before you can enable broadcast...
106 sock.setBroadcast(true); // turn on broadcast
107 if (node.multicast == "multi") {
109 sock.setMulticastTTL(128);
110 sock.addMembership(node.addr,node.iface); // Add to the multicast group
111 node.log('udp multicast ready : '+node.outport+' -> '+node.addr+":"+node.port);
113 if (e.errno == "EINVAL") {
114 node.error("Bad Multicast Address");
115 } else if (e.errno == "ENODEV") {
116 node.error("Must be ip address of the required interface");
118 node.error("Error :"+e.errno);
122 node.log('udp broadcast ready : '+node.outport+' -> '+node.addr+":"+node.port);
125 } else if (node.outport != "") {
126 sock.bind(node.outport);
127 node.log('udp ready : '+node.outport+' -> '+node.addr+":"+node.port);
129 node.log('udp ready : '+node.addr+":"+node.port);
132 node.on("input", function(msg) {
133 if (msg.payload != null) {
134 var add = node.addr || msg.ip || "";
135 var por = node.port || msg.port || 0;
137 node.warn("udp: ip address not set");
138 } else if (por == 0) {
139 node.warn("udp: port not set");
140 } else if (isNaN(por) || (por < 1) || (por > 65535)) {
141 node.warn("udp: port number not valid");
145 message = new Buffer(msg.payload, 'base64');
146 } else if (msg.payload instanceof Buffer) {
147 message = msg.payload;
149 message = new Buffer(""+msg.payload);
151 sock.send(message, 0, message.length, por, add, function(err, bytes) {
153 node.error("udp : "+err);
161 node.on("close", function() {
164 node.log('udp output stopped');
170 RED.nodes.registerType("udp out",UDPout);