├── .gitignore ├── LICENSE ├── README.md ├── UpdateSettingsConnection.py ├── enumerations.js ├── examples └── printActiveConnections.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Pascal Garber 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | node-networkmanager 2 | =================== 3 | 4 | Controll the [NetworkManager](https://wiki.gnome.org/Projects/NetworkManager) with Node.js 5 | 6 | # Dokumentation 7 | * Official D-Bus Reference Manual: https://developer.gnome.org/NetworkManager/0.9/ 8 | * Official D-Bus Interface Specification: https://developer.gnome.org/NetworkManager/0.9/spec.html 9 | 10 | This Dokumentation is based on the Dokumentation for the [python-networkmanager](https://pythonhosted.org/python-networkmanager/). 11 | 12 | ## Node.js API to talk to NetworkManager 13 | NetworkManager provides a detailed and capable D-Bus interface on the system bus. You can use this interface to query NetworkManager about the overall state of the network and details of network devices like current IP addresses or DHCP options, and to activate and deactivate network connections. 14 | 15 | node-networkmanager takes this D-Bus interface and wraps D-Bus interfaces in objects and D-Bus properties in getter and setter functions. 16 | 17 | ## The NetworkManager module 18 | All the code is contained in one module: NetworkManager. Using it is very simple: 19 | ``` 20 | var networkmanager = require('networkmanager'); 21 | networkmanager.connect(function (error, networkmanager) { 22 | networkmanager.NetworkManager.GetVersion(function(error, Version) { 23 | console.log("NetworkManager Version: "+Version); 24 | }); 25 | }); 26 | ``` 27 | 28 | NetworkManager exposes a lot of information via D-Bus and also allows full control of network settings. The full D-Bus API can be found on [NetworkManager project website](https://developer.gnome.org/NetworkManager/0.9/spec.html 29 | ). All interfaces listed there have been wrapped in objects as listed below. With a few exceptions, they behave exactly like the D-Bus methods. These exceptions are for convenience and limited to this list: 30 | * IP addresses are returned as strings of the form 1.2.3.4 instead of network byte ordered integers. 31 | * Route metrics are returned in host byte order, so you can use them as integers. 32 | * Mac addresses and BSSIDs are always returned as strings of the form 00:11:22:33:44:55 instead of byte sequences. 33 | * Wireless SSID’s are returned as strings instead of byte sequences. 34 | * Enumerated types wrapped to objects including the enumerated type index, the name and the description. 35 | * All D-Bus properties are exposed as getters and setters, e.g. ```NetworkManager.Version``` is wrapped to ```NetworkManager.GetVersion``` 36 | * Callback values are automatically converted to JavaScript types (thanky to [node-dbus](https://github.com/Shouqun/node-dbus)) 37 | * Object paths in return values are automatically replaced with proxy objects, so you don’t need to do that manually 38 | 39 | ## List of objects 40 | TODO.. 41 | -------------------------------------------------------------------------------- /UpdateSettingsConnection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 3 | # 4 | 5 | # 6 | # The MIT License (MIT) 7 | # 8 | # Copyright (c) 2014 Pascal Garber 9 | # 10 | # Permission is hereby granted, free of charge, to any person obtaining a copy 11 | # of this software and associated documentation files (the "Software"), to deal 12 | # in the Software without restriction, including without limitation the rights 13 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | # copies of the Software, and to permit persons to whom the Software is 15 | # furnished to do so, subject to the following conditions: 16 | # 17 | # The above copyright notice and this permission notice shall be included in all 18 | # copies or substantial portions of the Software. 19 | # 20 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | # SOFTWARE. 27 | # 28 | 29 | # 30 | # This example updates a connection's IPv4 method with the Update() method. 31 | # 32 | # Configuration settings are described at 33 | # https://developer.gnome.org/NetworkManager/0.9/ref-settings.html 34 | # 35 | 36 | # 37 | # Example Settings 38 | # 39 | # dbus.Dictionary({ 40 | # dbus.String(u'802-3-ethernet'): dbus.Dictionary({ 41 | # dbus.String(u'duplex'): dbus.String(u'full', variant_level=1), 42 | # dbus.String(u's390-options'): dbus.Dictionary( 43 | # {}, signature=dbus.Signature('ss'), variant_level=1) 44 | # }, signature=dbus.Signature('sv')), 45 | # dbus.String(u'connection'): dbus.Dictionary({ 46 | # dbus.String(u'timestamp'): dbus.UInt64(1406541002L, variant_level=1), 47 | # dbus.String(u'type'): dbus.String(u'802-3-ethernet', variant_level=1), 48 | # dbus.String(u'id'): dbus.String(u'Bugwelder', variant_level=1), 49 | # dbus.String(u'uuid'): dbus.String(u'ed23c3bc-63a9-408c-826f-c1318f61088b', variant_level=1) 50 | # }, signature=dbus.Signature('sv')), 51 | # dbus.String(u'ipv4'): dbus.Dictionary({ 52 | # dbus.String(u'routes'): dbus.Array([], signature=dbus.Signature('au'), variant_level=1), 53 | # dbus.String(u'addresses'): dbus.Array([ 54 | # dbus.Array([ 55 | # dbus.UInt32(364030144L), 56 | # dbus.UInt32(24L), 57 | # dbus.UInt32(28485824L) 58 | # ], signature=dbus.Signature('u') 59 | # )], signature=dbus.Signature('au'), variant_level=1), 60 | # dbus.String(u'dns'): dbus.Array([], signature=dbus.Signature('u'), variant_level=1), 61 | # dbus.String(u'method'): dbus.String(u'manual', variant_level=1) 62 | # }, signature=dbus.Signature('sv')) 63 | # }, signature=dbus.Signature('sa{sv}')) 64 | # 65 | # dbus.Dictionary({ 66 | # dbus.String(u'802-11-wireless'): dbus.Dictionary({ 67 | # dbus.String(u'seen-bssids'): dbus.Array([ 68 | # dbus.String(u'A0:F3:C1:48:D7:3E') 69 | # ], signature=dbus.Signature('s'), variant_level=1), 70 | # dbus.String(u'ssid'): dbus.Array([ 71 | # dbus.Byte(104), dbus.Byte(97), dbus.Byte(109), dbus.Byte(98), dbus.Byte(117), dbus.Byte(114), dbus.Byte(103), dbus.Byte(46), dbus.Byte(102), dbus.Byte(114), dbus.Byte(101), dbus.Byte(105), dbus.Byte(102), dbus.Byte(117), dbus.Byte(110), dbus.Byte(107), dbus.Byte(46), dbus.Byte(110), dbus.Byte(101), dbus.Byte(116) 72 | # ], signature=dbus.Signature('y'), variant_level=1), 73 | # dbus.String(u'mac-address'): dbus.Array([ 74 | # dbus.Byte(120), dbus.Byte(146), dbus.Byte(156), dbus.Byte(9), dbus.Byte(247), dbus.Byte(250) 75 | # ], signature=dbus.Signature('y'), variant_level=1), 76 | # dbus.String(u'mode'): dbus.String(u'infrastructure', variant_level=1) 77 | # }, signature=dbus.Signature('sv')), 78 | # dbus.String(u'connection'): dbus.Dictionary({ 79 | # dbus.String(u'timestamp'): dbus.UInt64(1406576722L, variant_level=1), 80 | # dbus.String(u'type'): dbus.String(u'802-11-wireless', variant_level=1), 81 | # dbus.String(u'id'): dbus.String(u'hamburg.freifunk.net', variant_level=1), 82 | # dbus.String(u'uuid'): dbus.String(u'00245195-e827-425b-b8cc-0157797f71c6', variant_level=1) 83 | # }, signature=dbus.Signature('sv')), 84 | # dbus.String(u'ipv4'): dbus.Dictionary({ 85 | # dbus.String(u'routes'): dbus.Array([], signature=dbus.Signature('au'), variant_level=1), 86 | # dbus.String(u'addresses'): dbus.Array([], signature=dbus.Signature('au'), variant_level=1), 87 | # dbus.String(u'dns'): dbus.Array([], signature=dbus.Signature('u'), variant_level=1), 88 | # dbus.String(u'method'): dbus.String(u'auto', variant_level=1)}, signature=dbus.Signature('sv')), 89 | # dbus.String(u'ipv6'): dbus.Dictionary({ 90 | # dbus.String(u'routes'): dbus.Array([], signature=dbus.Signature('(ayuayu)'), variant_level=1), 91 | # dbus.String(u'addresses'): dbus.Array([], signature=dbus.Signature('(ayuay)'), variant_level=1), 92 | # dbus.String(u'dns'): dbus.Array([], signature=dbus.Signature('ay'), variant_level=1), 93 | # dbus.String(u'method'): dbus.String(u'auto', variant_level=1) 94 | # }, signature=dbus.Signature('sv')) 95 | # }, signature=dbus.Signature('sa{sv}')) 96 | # 97 | 98 | 99 | import socket, struct, dbus, sys, json 100 | 101 | if len(sys.argv) < 3: 102 | print "Usage: %s " % sys.argv[0] 103 | sys.exit(1) 104 | 105 | def warning(message): 106 | sys.stderr.write("WARNING: %s\n" % message) 107 | 108 | def parse_array_of_string(array): 109 | dbus_array = dbus.Array([], signature=dbus.Signature('s'), variant_level=1) 110 | for string_val in array: 111 | dbus_array.append(dbus.String(string_val)) 112 | return dbus_array 113 | 114 | def parse_array_of_byte(array): 115 | dbus_array = dbus.Array([], signature=dbus.Signature('y'), variant_level=1) 116 | for byte_val in array: 117 | dbus_array.append(dbus.Byte(byte_val)) 118 | return dbus_array 119 | 120 | def parse_array_of_uint32(array): 121 | dbus_array = dbus.Array([], signature=dbus.Signature('u')) 122 | for uint32val in array: 123 | dbus_array.append(dbus.UInt32(uint32val)) 124 | return dbus_array 125 | 126 | def parse_array_of_array_of_uint32(array): 127 | dbus_array_of_array = dbus.Array([], signature=dbus.Signature('au'), variant_level=1) 128 | for val in array: 129 | dbus_array_of_array.append(parse_array_of_uint32(val)) 130 | return dbus_array_of_array 131 | 132 | 133 | def parse_settings(settings): 134 | 135 | # ethernet = getattr(settings, '802-3-ethernet', None) 136 | # if ethernet is not None: 137 | # # print(settings['802-3-ethernet']) 138 | # print(ethernet) 139 | dbus_settings = dbus.Dictionary({}, signature=dbus.Signature('sa{sv}')) 140 | 141 | for settings_key in settings: 142 | 143 | if settings_key == '802-11-wireless': 144 | dbus_wireless = dbus.Dictionary({}, signature=dbus.Signature('sv'), variant_level=1); 145 | 146 | for wireless_key in settings[settings_key]: 147 | if wireless_key == 'seen-bssids': 148 | dbus_wireless[dbus.String(wireless_key)] = parse_array_of_string(settings[settings_key][wireless_key]); 149 | elif wireless_key == 'ssid': 150 | dbus_wireless[dbus.String(wireless_key)] = parse_array_of_byte(settings[settings_key][wireless_key]); 151 | elif wireless_key == 'mac-address': 152 | dbus_wireless[dbus.String(wireless_key)] = parse_array_of_byte(settings[settings_key][wireless_key]); 153 | elif wireless_key == 'mode': 154 | dbus_wireless[dbus.String(wireless_key)] = dbus.String(settings[settings_key][wireless_key], variant_level=1) 155 | elif wireless_key == 'security': 156 | dbus_wireless[dbus.String(wireless_key)] = dbus.String(settings[settings_key][wireless_key], variant_level=1) 157 | else: 158 | warning('802-11-wireless property %s not supported yet!' % wireless_key) 159 | 160 | dbus_settings[dbus.String(settings_key)] = dbus_wireless; 161 | 162 | elif settings_key == '802-3-ethernet': 163 | dbus_ethernet = dbus.Dictionary({}, signature=dbus.Signature('sv'), variant_level=1); 164 | 165 | for ethernet_key in settings[settings_key]: 166 | if ethernet_key == 'duplex': 167 | dbus_ethernet[dbus.String(ethernet_key)] = dbus.String(settings[settings_key][ethernet_key], variant_level=1); 168 | elif ethernet_key == 's390-options': 169 | warning('%s property %s not supported yet!' % (settings_key, ethernet_key)) 170 | else: 171 | warning('%s property %s not supported yet!' % (settings_key, ethernet_key)) 172 | 173 | dbus_settings[dbus.String(settings_key)] = dbus_ethernet; 174 | 175 | elif settings_key == 'connection': 176 | dbus_connection = dbus.Dictionary({}, signature=dbus.Signature('sv')); 177 | 178 | for connection_key in settings[settings_key]: 179 | 180 | if connection_key == 'timestamp': 181 | dbus_connection[dbus.String(connection_key)] = dbus.UInt64(settings[settings_key][connection_key], variant_level=1) 182 | elif connection_key == 'type': 183 | dbus_connection[dbus.String(connection_key)] = dbus.String(settings[settings_key][connection_key], variant_level=1) 184 | elif connection_key == 'id': 185 | dbus_connection[dbus.String(connection_key)] = dbus.String(settings[settings_key][connection_key], variant_level=1) 186 | elif connection_key == 'uuid': 187 | dbus_connection[dbus.String(connection_key)] = dbus.String(settings[settings_key][connection_key], variant_level=1) 188 | else: 189 | warning('%s property %s not supported yet!' % (settings_key, connection_key)) 190 | 191 | dbus_settings[dbus.String(settings_key)] = dbus_connection 192 | 193 | elif settings_key == '802-11-wireless-security': 194 | dbus_security = dbus.Dictionary({}, signature=dbus.Signature('sv')) 195 | for security_key in settings[settings_key]: 196 | if security_key == 'key-mgmt': 197 | dbus_security[dbus.String(security_key)] = dbus.String(settings[settings_key][security_key], variant_level=1) 198 | elif security_key == 'auth-alg': 199 | dbus_security[dbus.String(security_key)] = dbus.String(settings[settings_key][security_key], variant_level=1) 200 | elif security_key == 'psk': 201 | dbus_security[dbus.String(security_key)] = dbus.String(settings[settings_key][security_key], variant_level=1) 202 | else: 203 | warning('%s property %s not supported yet!' % (settings_key, security_key)) 204 | dbus_settings[dbus.String(settings_key)] = dbus_security 205 | 206 | elif settings_key == 'ipv4': 207 | dbus_ipv4 = dbus.Dictionary({}, signature=dbus.Signature('sv')) 208 | 209 | for ipv4_key in settings[settings_key]: 210 | if ipv4_key == 'routes': 211 | dbus_ipv4[dbus.String(ipv4_key)] = parse_array_of_array_of_uint32(settings[settings_key][ipv4_key]) 212 | elif ipv4_key == 'addresses': 213 | dbus_ipv4[dbus.String(ipv4_key)] = parse_array_of_array_of_uint32(settings[settings_key][ipv4_key]) 214 | elif ipv4_key == 'dns': 215 | dbus_ipv4[dbus.String(ipv4_key)] = parse_array_of_uint32(settings[settings_key][ipv4_key]) 216 | elif ipv4_key == 'method': 217 | dbus_ipv4[dbus.String(ipv4_key)] = dbus.String(settings[settings_key][ipv4_key], variant_level=1) 218 | else: 219 | warning('%s property %s not supported yet!' % (settings_key, ipv4_key)) 220 | 221 | dbus_settings[dbus.String(settings_key)] = dbus_ipv4; 222 | 223 | elif settings_key == 'ipv6': 224 | warning('ipv6 settings not supported yet!') 225 | else: 226 | warning('%s settings not supported yet!' % settings_key) 227 | 228 | return dbus_settings 229 | 230 | objectPath = sys.argv[1] 231 | settings = json.loads(sys.argv[2]) 232 | 233 | # print(settings) 234 | dbus_settings = parse_settings(settings) 235 | # print(dbus_settings) 236 | 237 | 238 | bus = dbus.SystemBus() 239 | proxy = bus.get_object("org.freedesktop.NetworkManager", objectPath) 240 | SettingsConnection = dbus.Interface(proxy, "org.freedesktop.NetworkManager.Settings.Connection") 241 | 242 | # old_settings = SettingsConnection.GetSettings() 243 | # print("\nold settings: ") 244 | # print(old_settings) 245 | 246 | # Save all the updated settings back to NetworkManager 247 | SettingsConnection.Update(dbus_settings) 248 | 249 | sys.exit(0) -------------------------------------------------------------------------------- /enumerations.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'NM_STATE': function (code) { 3 | var result = { 4 | code: code, 5 | name: 'UNKNOWN', 6 | description: 'Networking state is unknown.' 7 | }; 8 | switch(code) { 9 | case 10: 10 | result.name = 'ASLEEP'; 11 | result.description = 'Networking is inactive and all devices are disabled.'; 12 | break; 13 | case 20: 14 | result.name = 'DISCONNECTED'; 15 | result.description = 'There is no active network connection.'; 16 | break; 17 | case 30: 18 | result.name = 'DISCONNECTING'; 19 | result.description = 'Network connections are being cleaned up.'; 20 | break; 21 | case 40: 22 | result.name = 'CONNECTING'; 23 | result.description = 'A network device is connecting to a network and there is no other available network connection.'; 24 | break; 25 | case 50: 26 | result.name = 'CONNECTED_LOCAL'; 27 | result.description = 'A network device is connected, but there is only link-local connectivity.'; 28 | break; 29 | case 60: 30 | result.name = 'CONNECTED_SITE'; 31 | result.description = 'A network device is connected, but there is only site-local connectivity.'; 32 | break; 33 | case 70: 34 | result.name = 'CONNECTED_GLOBAL'; 35 | result.description = 'A network device is connected, with global network connectivity.'; 36 | break; 37 | } 38 | return result; 39 | }, 40 | 'NM_ACTIVE_CONNECTION_STATE': function (code) { 41 | var result = { 42 | code: code, 43 | name: 'UNKNOWN', 44 | description: 'The active connection is in an unknown state.' 45 | }; 46 | switch(code) { 47 | case 1: 48 | result.name = 'ACTIVATING'; 49 | result.description = 'The connection is activating.'; 50 | break; 51 | case 2: 52 | result.name = 'ACTIVATED'; 53 | result.description = 'The connection is activated.'; 54 | break; 55 | case 3: 56 | result.name = 'DEACTIVATING'; 57 | result.description = 'The connection is being torn down and cleaned up.'; 58 | break; 59 | case 4: 60 | result.name = 'DEACTIVATED'; 61 | result.description = 'The connection is no longer active.'; 62 | break; 63 | } 64 | return result; 65 | }, 66 | 'NM_DEVICE_STATE': function (code) { 67 | var result = { 68 | code: code, 69 | name: 'UNKNOWN', 70 | description: 'The device is in an unknown state.' 71 | }; 72 | switch(code) { 73 | case 10: 74 | result.name = 'UNMANAGED'; 75 | result.description = 'The device is recognized but not managed by NetworkManager.'; 76 | break; 77 | case 20: 78 | result.name = 'UNAVAILABLE'; 79 | result.description = 'The device cannot be used (carrier off, rfkill, etc).'; 80 | break; 81 | case 30: 82 | result.name = 'DISCONNECTED'; 83 | result.description = 'The device is not connected.'; 84 | break; 85 | case 40: 86 | result.name = 'PREPARE'; 87 | result.description = 'The device is preparing to connect.'; 88 | break; 89 | case 50: 90 | result.name = 'CONFIG'; 91 | result.description = 'The device is being configured.'; 92 | break; 93 | case 60: 94 | result.name = 'NEED_AUTH'; 95 | result.description = 'The device is awaiting secrets necessary to continue connection.'; 96 | break; 97 | case 70: 98 | result.name = 'IP_CONFIG'; 99 | result.description = 'The IP settings of the device are being requested and configured.'; 100 | break; 101 | case 80: 102 | result.name = 'IP_CHECK'; 103 | result.description = "The device's IP connectivity ability is being determined."; 104 | break; 105 | case 90: 106 | result.name = 'SECONDARIES'; 107 | result.description = 'The device is waiting for secondary connections to be activated.'; 108 | break; 109 | case 100: 110 | result.name = 'ACTIVATED'; 111 | result.description = 'The device is active.'; 112 | break; 113 | case 110: 114 | result.name = 'DEACTIVATING'; 115 | result.description = "The device's network connection is being torn down."; 116 | break; 117 | case 120: 118 | result.name = 'FAILED'; 119 | result.description = 'The device is in a failure state following an attempt to activate it.'; 120 | break; 121 | } 122 | return result; 123 | }, 124 | 'NM_DEVICE_STATE_REASON': function (code) { 125 | var result = { 126 | code: code, 127 | name: 'UNKNOWN', 128 | description: 'The reason for the device state change is unknown.' 129 | }; 130 | switch(code) { 131 | case 1: 132 | result.name = 'NONE'; 133 | result.description = 'The state change is normal.'; 134 | break; 135 | case 2: 136 | result.name = 'NOW_MANAGED'; 137 | result.description = 'The device is now managed.'; 138 | break; 139 | case 3: 140 | result.name = 'UNMANAGED'; 141 | result.description = 'The device is no longer managed.'; 142 | break; 143 | case 4: 144 | result.name = 'CONFIG_FAILED'; 145 | result.description = 'The device could not be readied for configuration.'; 146 | break; 147 | case 5: 148 | result.name = 'CONFIG_UNAVAILABLE'; 149 | result.description = 'IP configuration could not be reserved (no available address, timeout, etc).'; 150 | break; 151 | case 6: 152 | result.name = 'CONFIG_EXPIRED'; 153 | result.description = 'The IP configuration is no longer valid.'; 154 | break; 155 | case 7: 156 | result.name = 'NO_SECRETS'; 157 | result.description = 'Secrets were required, but not provided.'; 158 | break; 159 | case 8: 160 | result.name = 'SUPPLICANT_DISCONNECT'; 161 | result.description = "The 802.1X supplicant disconnected from the access point or authentication server."; 162 | break; 163 | case 9: 164 | result.name = 'SUPPLICANT_CONFIG_FAILED'; 165 | result.description = 'Configuration of the 802.1X supplicant failed.'; 166 | break; 167 | case 10: 168 | result.name = 'SUPPLICANT_FAILED'; 169 | result.description = 'The 802.1X supplicant quit or failed unexpectedly.'; 170 | break; 171 | case 11: 172 | result.name = 'SUPPLICANT_TIMEOUT'; 173 | result.description = "The 802.1X supplicant took too long to authenticate."; 174 | break; 175 | case 12: 176 | result.name = 'PPP_START_FAILED'; 177 | result.description = 'The PPP service failed to start within the allowed time.'; 178 | break; 179 | case 13: 180 | result.name = 'PPP_DISCONNECT'; 181 | result.description = 'The PPP service disconnected unexpectedly.'; 182 | break; 183 | case 14: 184 | result.name = 'PPP_FAILED'; 185 | result.description = 'The PPP service quit or failed unexpectedly.'; 186 | break; 187 | case 15: 188 | result.name = 'DHCP_START_FAILED'; 189 | result.description = 'The DHCP service failed to start within the allowed time.'; 190 | break; 191 | case 16: 192 | result.name = 'DHCP_ERROR'; 193 | result.description = 'The DHCP service reported an unexpected error.'; 194 | break; 195 | case 17: 196 | result.name = 'DHCP_FAILED'; 197 | result.description = 'The DHCP service quit or failed unexpectedly.'; 198 | break; 199 | case 18: 200 | result.name = 'SHARED_START_FAILED'; 201 | result.description = 'The shared connection service failed to start.'; 202 | break; 203 | case 19: 204 | result.name = 'SHARED_FAILED'; 205 | result.description = 'The shared connection service quit or failed unexpectedly.'; 206 | break; 207 | case 20: 208 | result.name = 'AUTOIP_START_FAILED'; 209 | result.description = 'The AutoIP service failed to start.'; 210 | break; 211 | case 21: 212 | result.name = 'AUTOIP_ERROR'; 213 | result.description = 'The AutoIP service reported an unexpected error.'; 214 | break; 215 | case 22: 216 | result.name = 'AUTOIP_FAILED'; 217 | result.description = 'The AutoIP service quit or failed unexpectedly.'; 218 | break; 219 | case 23: 220 | result.name = 'MODEM_BUSY'; 221 | result.description = 'Dialing failed because the line was busy.'; 222 | break; 223 | case 24: 224 | result.name = 'MODEM_NO_DIAL_TONE'; 225 | result.description = 'Dialing failed because there was no dial tone.'; 226 | break; 227 | case 25: 228 | result.name = 'MODEM_NO_CARRIER'; 229 | result.description = 'Dialing failed because there was carrier.'; 230 | break; 231 | case 26: 232 | result.name = 'MODEM_DIAL_TIMEOUT'; 233 | result.description = 'Dialing timed out.'; 234 | break; 235 | case 27: 236 | result.name = 'MODEM_DIAL_FAILED'; 237 | result.description = 'Dialing failed.'; 238 | break; 239 | case 28: 240 | result.name = 'MODEM_INIT_FAILED'; 241 | result.description = 'Modem initialization failed.'; 242 | break; 243 | case 29: 244 | result.name = 'GSM_APN_FAILED'; 245 | result.description = 'Failed to select the specified GSM APN.'; 246 | break; 247 | case 30: 248 | result.name = 'GSM_REGISTRATION_NOT_SEARCHING'; 249 | result.description = 'Not searching for networks.'; 250 | break; 251 | case 31: 252 | result.name = 'GSM_REGISTRATION_DENIED'; 253 | result.description = 'Network registration was denied.'; 254 | break; 255 | case 32: 256 | result.name = 'GSM_REGISTRATION_TIMEOUT'; 257 | result.description = 'Network registration timed out.'; 258 | break; 259 | case 33: 260 | result.name = 'GSM_REGISTRATION_FAILED'; 261 | result.description = 'Failed to register with the requested GSM network.'; 262 | break; 263 | case 34: 264 | result.name = 'GSM_PIN_CHECK_FAILED'; 265 | result.description = 'PIN check failed.'; 266 | break; 267 | case 35: 268 | result.name = 'FIRMWARE_MISSING'; 269 | result.description = 'Necessary firmware for the device may be missing.'; 270 | break; 271 | case 36: 272 | result.name = 'REMOVED'; 273 | result.description = 'The device was removed.'; 274 | break; 275 | case 37: 276 | result.name = 'SLEEPING'; 277 | result.description = 'NetworkManager went to sleep.'; 278 | break; 279 | case 38: 280 | result.name = 'CONNECTION_REMOVED'; 281 | result.description = "The device's active connection was removed or disappeared."; 282 | break; 283 | case 39: 284 | result.name = 'USER_REQUESTED'; 285 | result.description = 'A user or client requested the disconnection.'; 286 | break; 287 | case 40: 288 | result.name = 'CARRIER'; 289 | result.description = "The device's carrier/link changed."; 290 | break; 291 | case 41: 292 | result.name = 'CONNECTION_ASSUMED'; 293 | result.description = "The device's existing connection was assumed."; 294 | break; 295 | case 42: 296 | result.name = 'SUPPLICANT_AVAILABLE'; 297 | result.description = 'The 802.1x supplicant is now available.'; 298 | break; 299 | case 43: 300 | result.name = 'MODEM_NOT_FOUND'; 301 | result.description = 'The modem could not be found.'; 302 | break; 303 | case 44: 304 | result.name = 'BT_FAILED'; 305 | result.description = 'The Bluetooth connection timed out or failed.'; 306 | break; 307 | case 45: 308 | result.name = 'GSM_SIM_NOT_INSERTED'; 309 | result.description = "GSM Modem's SIM Card not inserted."; 310 | break; 311 | case 46: 312 | result.name = 'GSM_SIM_PIN_REQUIRED'; 313 | result.description = "GSM Modem's SIM Pin required."; 314 | break; 315 | case 47: 316 | result.name = 'GSM_SIM_PUK_REQUIRED'; 317 | result.description = "GSM Modem's SIM Puk required."; 318 | break; 319 | case 48: 320 | result.name = 'GSM_SIM_WRONG'; 321 | result.description = "GSM Modem's SIM wrong"; 322 | break; 323 | case 49: 324 | result.name = 'INFINIBAND_MODE'; 325 | result.description = 'InfiniBand device does not support connected mode.'; 326 | break; 327 | case 50: 328 | result.name = 'DEPENDENCY_FAILED'; 329 | result.description = 'A dependency of the connection failed.'; 330 | break; 331 | case 51: 332 | result.name = 'BR2684_FAILED'; 333 | result.description = 'Problem with the RFC 2684 Ethernet over ADSL bridge.'; 334 | break; 335 | case 52: 336 | result.name = 'MODEM_MANAGER_UNAVAILABLE'; 337 | result.description = 'ModemManager was not running or quit unexpectedly.'; 338 | break; 339 | case 53: 340 | result.name = 'SSID_NOT_FOUND'; 341 | result.description = 'The 802.11 Wi-Fi network could not be found.'; 342 | break; 343 | case 54: 344 | result.name = 'SECONDARY_CONNECTION_FAILED'; 345 | result.description = 'A secondary connection of the base connection failed.'; 346 | break; 347 | } 348 | return result; 349 | }, 350 | 'NM_DEVICE_TYPE': function (code) { 351 | var result = { 352 | code: code, 353 | name: 'UNKNOWN', 354 | description: 'The device type is unknown.' 355 | }; 356 | switch(code) { 357 | case 1: 358 | result.name = 'ETHERNET'; 359 | result.description = 'The device is wired Ethernet device.'; 360 | break; 361 | case 2: 362 | result.name = 'WIFI'; 363 | result.description = 'The device is an 802.11 WiFi device.'; 364 | break; 365 | case 3: 366 | result.name = 'UNUSED1'; 367 | result.description = 'Unused'; 368 | break; 369 | case 4: 370 | result.name = 'UNUSED2'; 371 | result.description = 'Unused'; 372 | break; 373 | case 5: 374 | result.name = 'BT'; 375 | result.description = 'The device is Bluetooth device that provides PAN or DUN capabilities.'; 376 | break; 377 | case 6: 378 | result.name = 'OLPC_MESH'; 379 | result.description = 'The device is an OLPC mesh networking device.'; 380 | break; 381 | case 7: 382 | result.name = 'WIMAX'; 383 | result.description = 'The device is an 802.16e Mobile WiMAX device.'; 384 | break; 385 | case 8: 386 | result.name = 'MODEM'; 387 | result.description = 'The device is a modem supporting one or more of analog telephone, CDMA/EVDO, GSM/UMTS/HSPA, or LTE standards to access a cellular or wireline data network.'; 388 | break; 389 | case 9: 390 | result.name = 'INFINIBAND'; 391 | result.description = 'The device is an IP-capable InfiniBand interface.'; 392 | break; 393 | case 10: 394 | result.name = 'BOND'; 395 | result.description = 'The device is a bond master interface.'; 396 | break; 397 | case 11: 398 | result.name = 'VLAN'; 399 | result.description = 'The device is a VLAN interface.'; 400 | break; 401 | case 12: 402 | result.name = 'ADSL'; 403 | result.description = 'The device is an ADSL device supporting PPPoE and PPPoATM protocols.'; 404 | break; 405 | case 13: 406 | result.name = 'BRIDGE'; 407 | result.description = 'The device is a bridge interface.'; 408 | break; 409 | 410 | } 411 | return result; 412 | }, 413 | // device = "wireless device" || "access point" 414 | 'NM_802_11_MODE': function (code, device) { 415 | var result = { 416 | code: code, 417 | name: 'UNKNOWN', 418 | description: 'Mode is unknown.' 419 | }; 420 | switch(code) { 421 | case 1: 422 | result.name = 'ADHOC'; 423 | if(!device) result.description = 'For both devices and access point objects, indicates the object is part of an Ad-Hoc 802.11 network without a central coordinating access point.'; 424 | else if(device == "wireless device") result.description = 'The wireless device is part of an Ad-Hoc 802.11 network without a central coordinating access point.'; 425 | else result.description = 'The access point is part of an Ad-Hoc 802.11 network without a central coordinating access point.'; 426 | break; 427 | case 2: 428 | result.name = 'INFRA'; 429 | if(!device) result.description = 'The wireless device or access point is in infrastructure mode. For devices, this indicates the device is an 802.11 client/station. For access point objects, this indicates the object is an access point that provides connectivity to clients.'; 430 | else if(device == "wireless device") result.description = 'The wireless device is in infrastructure mode, this indicates the device is an 802.11 client/station.'; 431 | else result.description = 'The access point is in infrastructure mode, this indicates the object is an access point that provides connectivity to clients.'; 432 | break; 433 | case 3: 434 | result.name = 'AP'; 435 | if(!device) result.description = 'The device is an access point/hotspot. Not valid for access point objects themselves.'; 436 | else if(device == "wireless device") result.description = 'The device is an access point/hotspot.'; 437 | else result.description = 'This mode is not valid for access points.'; 438 | break; 439 | } 440 | return result; 441 | }, 442 | 'NM_DEVICE_CAP': function (code) { 443 | var result = { 444 | code: code, 445 | name: 'NONE', 446 | description: 'Null capability.' 447 | }; 448 | switch(code) { 449 | case 1: 450 | result.name = 'NM_SUPPORTED'; 451 | result.description = 'The device is supported by NetworkManager.'; 452 | break; 453 | case 2: 454 | result.name = 'CARRIER_DETECT'; 455 | result.description = 'The device supports carrier detection.'; 456 | break; 457 | } 458 | return result; 459 | }, 460 | 'NM_802_11_AP_FLAGS': function (code) { 461 | var result = { 462 | code: code, 463 | name: 'NONE', 464 | description: 'Null capability - says nothing about the access point.' 465 | }; 466 | switch(code) { 467 | case 1: 468 | result.name = 'PRIVACY'; 469 | result.description = 'Access point supports privacy measures.'; 470 | break; 471 | } 472 | return result; 473 | }, 474 | 'NM_802_11_AP_SEC': function (code) { 475 | var values = []; 476 | // 0x0 477 | if(code == 0) { 478 | values = [{ 479 | code: 0, 480 | name: 'NONE', 481 | description: 'Null flag.' 482 | }]; 483 | } 484 | // 0x1 485 | if(code & 1) { 486 | values.push({ 487 | code: 1, 488 | name: 'PAIR_WEP40', 489 | description: 'Access point supports pairwise 40-bit WEP encryption.' 490 | }); 491 | } 492 | // 0x2 493 | if(code & 2) { 494 | values.push({ 495 | code: 2, 496 | name: 'PAIR_WEP104', 497 | description: 'Access point supports pairwise 104-bit WEP encryption.' 498 | }); 499 | } 500 | // 0x4 501 | if(code & 4) { 502 | values.push({ 503 | code: 4, 504 | name: 'PAIR_TKIP', 505 | description: 'Access point supports pairwise TKIP encryption.' 506 | }); 507 | } 508 | // 0x8 509 | if(code & 8) { 510 | values.push({ 511 | code: 8, 512 | name: 'PAIR_CCMP', 513 | description: 'Access point supports pairwise CCMP encryption.' 514 | }); 515 | } 516 | // 0x10 517 | if(code & 16) { 518 | values.push({ 519 | code: 16, 520 | name: 'GROUP_WEP40', 521 | description: 'Access point supports a group 40-bit WEP cipher.' 522 | }); 523 | } 524 | // 0x20 525 | if(code & 32) { 526 | values.push({ 527 | code: 32, 528 | name: 'GROUP_WEP104', 529 | description: 'Access point supports a group 104-bit WEP cipher.' 530 | }); 531 | } 532 | // 0x40" 533 | if(code & 64) { 534 | values.push({ 535 | code: 64, 536 | name: 'GROUP_TKIP', 537 | description: 'Access point supports a group TKIP cipher.' 538 | }); 539 | } 540 | // 0x80 541 | if(code & 128) { 542 | values.push({ 543 | code: 128, 544 | name: 'GROUP_CCMP', 545 | description: 'Access point supports a group CCMP cipher.' 546 | }); 547 | } 548 | // 0x100 549 | if(code & 256) { 550 | values.push({ 551 | code: 256, 552 | name: 'KEY_MGMT_PSK', 553 | description: 'Access point supports PSK key management.' 554 | }); 555 | } 556 | // 0x200 557 | if(code & 512) { 558 | values.push({ 559 | code: 512, 560 | name: 'KEY_MGMT_802_1X', 561 | description: 'Access point supports 802.1x key management.' 562 | }); 563 | } 564 | return {flags:code, values:values}; 565 | }, 566 | 'NM_802_11_DEVICE_CAP': function (code) { 567 | var values = []; 568 | 569 | 570 | if(code == 0) { 571 | values = [{ 572 | code: 0, 573 | name: 'NONE', 574 | description: 'Null flag.' 575 | }]; 576 | } 577 | // 0x1 578 | if(code & 1) { 579 | values.push({ 580 | code: 1, 581 | name: 'CIPHER_WEP40', 582 | description: 'The device supports the 40-bit WEP cipher.' 583 | }); 584 | } 585 | // 0x2 586 | if(code & 2) { 587 | values.push({ 588 | code: 2, 589 | name: 'CIPHER_WEP104', 590 | description: 'The device supports the 104-bit WEP cipher.' 591 | }); 592 | } 593 | // 0x4 594 | if(code & 4) { 595 | values.push({ 596 | code: 4, 597 | name: 'CIPHER_TKIP', 598 | description: 'The device supports the TKIP cipher.' 599 | }); 600 | } 601 | // 0x8 602 | if(code & 8) { 603 | values.push({ 604 | code: 8, 605 | name: 'CIPHER_CCMP', 606 | description: 'The device supports the CCMP cipher.' 607 | }); 608 | } 609 | // 0x10 610 | if(code & 16) { 611 | values.push({ 612 | code: 16, 613 | name: 'WPA', 614 | description: 'The device supports the WPA encryption/authentication protocol.' 615 | }); 616 | } 617 | // 0x20 618 | if(code & 32) { 619 | values.push({ 620 | code: 32, 621 | name: 'RSN', 622 | description: 'The device supports the RSN encryption/authentication protocol.' 623 | }); 624 | } 625 | // 0x40" 626 | if(code & 64) { 627 | values.push({ 628 | code: 64, 629 | name: 'AP', 630 | description: 'The device supports Access Point mode.' 631 | }); 632 | } 633 | // 0x80 634 | if(code & 128) { 635 | values.push({ 636 | code: 128, 637 | name: 'ADHOC', 638 | description: 'The device supports Ad-Hoc mode.' 639 | }); 640 | } 641 | return {flags:code, values:values}; 642 | }, 643 | }; -------------------------------------------------------------------------------- /examples/printActiveConnections.js: -------------------------------------------------------------------------------- 1 | var networkmanager = require('../index.js'); 2 | var util = require('util'); 3 | 4 | var inspect = function(object) { 5 | console.log("\n"+util.inspect(object, showHidden=false, depth=2, colorize=true)+"\n"); 6 | } 7 | 8 | var getAccessPointInfo = function (AccessPoint) { 9 | AccessPoint.GetSsid(function(error, SsidString) { 10 | console.log("SSID: "+SsidString); 11 | }); 12 | 13 | AccessPoint.GetFlags(function(error, Flags) { 14 | console.log(Flags.description); 15 | }); 16 | 17 | 18 | AccessPoint.GetWpaFlags(function(error, WpaFlags) { 19 | //inspect(WpaFlags); 20 | for (var i = 0; i < WpaFlags.values.length; i++) { 21 | console.log("WpaFlag: "+WpaFlags.values[i].description); 22 | }; 23 | }); 24 | 25 | AccessPoint.GetRsnFlags(function(error, RsnFlags) { 26 | //inspect(RsnFlags); 27 | for (var i = 0; i < RsnFlags.values.length; i++) { 28 | console.log("RsnFlag: "+RsnFlags.values[i].description); 29 | }; 30 | }); 31 | 32 | AccessPoint.GetMaxBitrate(function(error, MaxBitrate) { 33 | console.log("AccessPoint max bitrate: "+MaxBitrate+" Kb/s"); 34 | }); 35 | 36 | AccessPoint.GetMode(function(error, Mode) { 37 | console.log("AccessPoint Mode: "+Mode.description); 38 | }); 39 | 40 | AccessPoint.GetStrength(function(error, Strength) { 41 | console.log("AccessPoint Strength: "+Strength+"%"); 42 | }); 43 | } 44 | 45 | var getIp4ConfigInfo = function (IP4Config) { 46 | IP4Config.GetDomains(function(error, Domains) { 47 | console.log("IPv4 Domains: "+Domains.toString()); 48 | }); 49 | 50 | IP4Config.GetAddresses(function(error, Addresses) { 51 | inspect({'IPv4 Addresses': Addresses}); 52 | }); 53 | } 54 | 55 | var getIp6ConfigInfo = function (IP6Config) { 56 | IP6Config.GetRoutes(function(error, Routes) { 57 | inspect({'IPv6 Routes': Routes}); 58 | }); 59 | IP6Config.GetDomains(function(error, Domains) { 60 | inspect({'IPv6 Domains': Domains}); 61 | }); 62 | IP6Config.GetNameservers(function(error, Nameservers) { 63 | inspect({'IPv6 Nameservers': Nameservers}); 64 | }); 65 | IP6Config.GetAddresses(function(error, Addresses) { 66 | inspect({'IPv6 Addresses': Addresses}); 67 | }); 68 | } 69 | 70 | var getDeviceInfo = function (Device) { 71 | 72 | Device.on('StateChanged', function (newState, oldState, reason) { 73 | if(newState) console.log("Device state changed: "+newState.description); 74 | if(reason) console.log("Device reason: "+reason.description); 75 | }); 76 | 77 | Device.GetCapabilities(function(error, Capabilities) { 78 | console.log(Capabilities.description); 79 | }); 80 | 81 | Device.GetDeviceType(function(error, DeviceType) { 82 | console.log(DeviceType.description); 83 | switch(DeviceType.name) { 84 | case 'ETHERNET': 85 | Device.GetSpeed(function(error, Speed) { 86 | console.log("Speed is "+Speed+" Mb/s"); 87 | }); 88 | break; 89 | case 'WIFI': 90 | Device.GetWirelessCapabilities(function(error, WirelessCapabilities) { 91 | for (var i = 0; i < WirelessCapabilities.values.length; i++) { 92 | console.log("WirelessCapabilities: "+WirelessCapabilities.values[i].description); 93 | }; 94 | }); 95 | 96 | Device.GetAccessPoints(function(error, AccessPoints) { 97 | // Array of visible access points 98 | for (var i = 0; i < AccessPoints.length; i++) { 99 | getAccessPointInfo(AccessPoints[i]); 100 | }; 101 | }); 102 | 103 | Device.GetBitrate(function(error, Bitrate) { 104 | console.log("Wireless Device Bitrate: "+Bitrate+" Kb/s"); 105 | }); 106 | 107 | Device.GetMode(function(error, Mode) { 108 | console.log("Wireless Device Mode: "+Mode.description); 109 | }); 110 | break; 111 | } 112 | }); 113 | 114 | Device.GetStateReason(function(error, State, Reason) { 115 | console.log(State.description); 116 | console.log(Reason.description); 117 | }); 118 | 119 | Device.GetIp4Config(function(error, Ip4Config) { 120 | if(!error && Ip4Config != null) getIp4ConfigInfo(Ip4Config); 121 | }); 122 | 123 | Device.GetIp6Config(function(error, Ip6Config) { 124 | if(!error && Ip6Config != null) getIp6ConfigInfo(Ip6Config); 125 | }); 126 | 127 | Device.GetAutoconnect(function(error, Autoconnect) { 128 | console.log("Autoconnect: "+Autoconnect); 129 | }); 130 | 131 | Device.GetFirmwareMissing(function(error, FirmwareMissing) { 132 | console.log("FirmwareMissing: "+FirmwareMissing); 133 | }); 134 | 135 | Device.GetManaged(function(error, Managed) { 136 | console.log("Managed: "+Managed); 137 | }); 138 | 139 | Device.GetDriver(function(error, Driver) { 140 | console.log("Driver: "+Driver); 141 | }); 142 | 143 | Device.GetInterface(function(error, Interface) { 144 | console.log("Interface: "+Interface); 145 | }); 146 | } 147 | 148 | var getSettingsConnectionInfo = function (SettingsConnection) { 149 | SettingsConnection.GetSettings(withSecrets = true, function(error, Settings) { 150 | inspect(Settings); 151 | 152 | // var hasSecrets = ['802-1x', '802-11-wireless-security', 'cdma', 'gsm', 'pppoe', 'vpn']; 153 | // hasSecrets.forEach(function(secretKey) { 154 | // if(Settings[secretKey]) { 155 | // console.log("=========== "+secretKey+" ==========="); 156 | // SettingsConnection.GetSecrets(secretKey, function(error, Secrets) { 157 | // console.log("================="); 158 | // inspect(error); 159 | // inspect(Secrets); // WARNING! This print out your Wireless Key! 160 | // console.log("================="); 161 | // }); 162 | // } 163 | // }); 164 | 165 | }); 166 | } 167 | 168 | var getActiveConnectionInfo = function (ActiveConnection) { 169 | 170 | ActiveConnection.GetSpecificObject(function(error, SpecificObject) { 171 | if(SpecificObject != null) getAccessPointInfo(SpecificObject); 172 | }); 173 | 174 | ActiveConnection.GetDevices(function(error, Devices) { 175 | for (var i = 0; i < Devices.length; i++) { 176 | getDeviceInfo(Devices[i]); 177 | }; 178 | }); 179 | 180 | ActiveConnection.GetConnection(function(error, SettingsConnection) { 181 | getSettingsConnectionInfo(SettingsConnection); 182 | }); 183 | 184 | // check active connection currently owns the default IPv4 route 185 | ActiveConnection.GetDefault(function(error, hasIPv4) { 186 | if(hasIPv4) console.log("The active connection use IPv4"); 187 | }); 188 | 189 | // check active connection currently owns the default IPv6 route 190 | ActiveConnection.GetDefault6(function(error, hasIPv6) { 191 | if(hasIPv6) console.log("The active connection use IPv6"); 192 | }); 193 | } 194 | 195 | networkmanager.connect(function (error, networkmanager) { 196 | 197 | networkmanager.NetworkManager.on('StateChanged', function(newState, oldState) { 198 | if(typeof oldState == 'undefined' || newState.code != oldState.code) { 199 | console.log("NetworkManager state changed: "+newState.description); 200 | } 201 | }); 202 | 203 | networkmanager.NetworkManager.GetVersion(function(error, Version) { 204 | console.log("NetworkManager Version: "+Version); 205 | }); 206 | 207 | networkmanager.NetworkManager.GetState(function(error, state) { 208 | console.log(state.description); 209 | }); 210 | 211 | networkmanager.NetworkManager.GetPrimaryConnection(function(error, PrimaryConnection) { 212 | // getActiveConnectionInfo(PrimaryConnection); 213 | }); 214 | 215 | // get all active connections 216 | networkmanager.NetworkManager.GetActiveConnections(function(error, ActiveConnections) { 217 | console.log("Count of active connections: "+ActiveConnections.length); 218 | for (var i = 0; i < ActiveConnections.length; i++) { 219 | getActiveConnectionInfo(ActiveConnections[i]); 220 | }; 221 | }); 222 | }); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | to old dokumentation? https://wiki.gnome.org/Projects/NetworkManager/DBusInterface/LatestDBusAPI 3 | new doku? https://developer.gnome.org/NetworkManager/unstable/spec.html 4 | current? https://developer.gnome.org/NetworkManager/0.9/spec.html 5 | see also: https://developer.gnome.org/NetworkManager/0.9/ 6 | */ 7 | 8 | 9 | var util = require('util'); 10 | var enums = require('./enumerations'); 11 | var extend = require('node.extend'); 12 | var async = require('async'); 13 | var Netmask = require('netmask').Netmask 14 | var spawn = require('child_process').spawn; 15 | var _debugEvent = require('debug')('event'); 16 | var debugEvent = function (name, arg1, arg2, arg3, arg4, arg5) { 17 | if(!arg1) arg1 = ''; 18 | if(!arg2) arg2 = ''; 19 | if(!arg3) arg3 = ''; 20 | if(!arg4) arg4 = ''; 21 | if(!arg5) arg5 = ''; 22 | _debugEvent(name, arg1, arg2, arg3, arg4, arg5); 23 | } 24 | var _debugIface = require('debug')('iface'); 25 | var debugIface = function(object) { 26 | if(_debugIface) 27 | _debugIface(object.interfaceName, "\n"+util.inspect(object, showHidden=false, depth=2, colorize=true)+"\n"); 28 | }; 29 | var _debug = require('debug')('info'); 30 | var debug = function(object) { 31 | if(_debug) 32 | _debug("\n"+util.inspect(object, showHidden=false, depth=2, colorize=true)+"\n"); 33 | }; 34 | var warn = require('debug')('warn'); 35 | var DBus = require('dbus'); 36 | var events = require('events'); 37 | 38 | var nm = {}; 39 | var bus; 40 | var TIMEOUTDELAY = 10000; 41 | var INTERVALDELAY = 100; 42 | 43 | var iface_cache = {}; 44 | 45 | /* 46 | * Wait for dbus service 47 | */ 48 | waitForService = function (findServiceName, timeoutDelay, intervalDelay, callback) { 49 | bus.getInterface('org.freedesktop.DBus', '/org/freedesktop/DBus', 'org.freedesktop.DBus', function(err, iface) { 50 | var timeout, interval; 51 | 52 | if(err) { return callback(err); } else { 53 | var checkService = function (callback) { 54 | debug("looking for dbus service"); 55 | iface.ListNames(function(err, serviceList) { 56 | for (index = 0; index < serviceList.length; ++index) { 57 | if(serviceList[index] === findServiceName) { 58 | return callback(true); 59 | } 60 | } 61 | return callback(false); 62 | }); 63 | } 64 | 65 | timeout = setTimeout(function () { 66 | debug("timeout"); 67 | clearInterval(interval); 68 | return callback("timeout"); 69 | }, timeoutDelay); 70 | 71 | interval = setInterval(function() { 72 | checkService(function (found) { 73 | if (found) { 74 | clearInterval(interval); 75 | clearTimeout(timeout); 76 | callback(null); 77 | } 78 | }); 79 | }, intervalDelay); 80 | } 81 | }); 82 | } 83 | 84 | var integrateMethods = function (valueToSet, iface, methodKeys) { 85 | methodKeys.forEach(function(methodKey) { 86 | valueToSet[methodKey] = function () { 87 | var arguments = Array.prototype.slice.call(arguments); 88 | iface[methodKey]['timeout'] = TIMEOUTDELAY; 89 | if(arguments.length >=0 && typeof(arguments[arguments.length-1]) == 'function') { 90 | var callback = arguments[arguments.length-1]; // last argument is callback 91 | iface[methodKey]['finish'] = function (result) { 92 | callback(null, result); 93 | } 94 | iface[methodKey]['error'] = function (error) { 95 | callback(error); 96 | } 97 | } 98 | debug("Call method "+methodKey+" with arguments: "); 99 | debug(arguments); 100 | // length + 1 argument for the callback 101 | if(iface.object.method[methodKey].in.length + 1 != arguments.length) { 102 | warn("Wrong count of arguments! Your count of arguments is "+arguments.length+", but the count should be "+iface.object.method[methodKey].in.length+1); 103 | } 104 | iface[methodKey].apply(iface, arguments); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply 105 | } 106 | }); 107 | } 108 | 109 | // type = "get" | "set" 110 | var integrateProperties = function (valueToSet, iface, propertyKeys) { 111 | propertyKeys.forEach(function(propertyKey) { 112 | if(iface.object.property[propertyKey].access == 'readwrite' || iface.object.property[propertyKey].access == 'read') { 113 | valueToSet['Get'+propertyKey] = function (callback) { 114 | iface.getProperty(propertyKey, callback); 115 | } 116 | } 117 | if(iface.object.property[propertyKey].access == 'readwrite' || iface.object.property[propertyKey].access == 'write') { 118 | valueToSet['Set'+propertyKey] = function (value, callback) { 119 | iface.setProperty(propertyKey, value, callback); 120 | } 121 | } 122 | }); 123 | 124 | valueToSet['GetAllProperties'] = function(callback) { 125 | return iface.getProperties(callback); 126 | } 127 | } 128 | 129 | var emitSignal = function (valueToSet, signalName, interfaceName, splitted, saveOldValue, valueKey, newValue, oldValue, otherValues) { 130 | var debugSignalName = signalName; 131 | if(splitted) { 132 | debugSignalName += " (PropertyChanged)"; 133 | } 134 | var emitParameters = [signalName, newValue, oldValue]; 135 | if(otherValues && otherValues.length > 0) { 136 | emitParameters.push.apply(emitParameters, otherValues); // https://stackoverflow.com/questions/13555652/dynamic-method-parameters 137 | } 138 | debugEvent(debugSignalName, interfaceName, newValue, oldValue, otherValues); 139 | valueToSet.emit.apply(valueToSet, emitParameters); // 1. arg is the signal name, 2. arg is the new value, 3. arg is the old value and the rest, for apply see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply 140 | if(saveOldValue) { 141 | valueToSet[valueKey] = newValue; // save current signal value for next time to know the old value 142 | } 143 | } 144 | 145 | var integrateSignals = function (valueToSet, iface, signalKeys) { 146 | 147 | if(signalKeys.length > 0) { 148 | var emitter = new events.EventEmitter(); 149 | valueToSet = extend(valueToSet, emitter); 150 | iface.removeAllListeners(); //lets just assume that we'll have no more than one instance of any interface 151 | signalKeys.forEach(function(signalKey) { 152 | iface.on(signalKey, function() { 153 | 154 | var args = Array.prototype.slice.call(arguments); 155 | var signalName = null; 156 | var splitted = false; 157 | var saveOldValue = true; 158 | var valueKey = null 159 | var newValue = null; 160 | var oldValue = null; 161 | var otherValues = null; 162 | 163 | switch(signalKey) { 164 | // split each property in the PropertiesChanged event to to a custom event 165 | case 'PropertiesChanged': 166 | var splitedSignalKeys = Object.keys(args[0]); 167 | splitedSignalKeys.forEach(function(signalKey) { 168 | 169 | signalName = signalKey+"Changed"; 170 | splitted = true; 171 | saveOldValue = true; 172 | valueKey = signalKey; 173 | newValue = args[0][signalKey]; 174 | oldValue = valueToSet[signalKey]; 175 | otherValues = null; 176 | 177 | switch(signalKey) { 178 | case 'State': 179 | switch(iface.interfaceName) { 180 | case 'org.freedesktop.NetworkManager': 181 | newValue = enums['NM_STATE'](newValue); 182 | break; 183 | default: 184 | break; 185 | } 186 | break; 187 | default: 188 | break; 189 | } 190 | }); 191 | break; 192 | case 'StateChanged': 193 | switch(iface.interfaceName) { 194 | case 'org.freedesktop.NetworkManager.Device': 195 | signalName = signalKey; 196 | valueKey = signalName.replace('Changed',''); 197 | splitted = false; 198 | saveOldValue = false; // In this case the new value does not need to be stored because we get the old value from the officell implementation 199 | newValue = enums['NM_DEVICE_STATE'](args[0]); 200 | oldValue = enums['NM_DEVICE_STATE'](args[1]); 201 | otherValues = [enums['NM_DEVICE_STATE_REASON'](args[2])]; 202 | break; 203 | case 'org.freedesktop.NetworkManager': 204 | default: 205 | signalName = signalKey; 206 | valueKey = signalName.replace('Changed',''); 207 | splitted = false; 208 | saveOldValue = true; 209 | newValue = enums['NM_STATE'](args[0]); 210 | oldValue = valueToSet[valueKey]; 211 | otherValues = null; 212 | break; 213 | } 214 | break; 215 | default: 216 | signalName = signalKey; 217 | valueKey = signalName.replace('Changed',''); 218 | splitted = false; 219 | saveOldValue = true; 220 | newValue = args[0]; 221 | oldValue = valueToSet[valueKey]; 222 | otherValues = null; 223 | } 224 | emitSignal(valueToSet, signalName, iface.interfaceName, splitted, saveOldValue, valueKey, newValue, oldValue, otherValues); 225 | }); 226 | }); 227 | } 228 | } 229 | 230 | var loadInterface = function (valueToSet, serviceName, objectPath, interfaceName, origCallback, createCallback) { 231 | var key = [serviceName, objectPath, interfaceName].join(':'); 232 | if (iface_cache[key]) { 233 | origCallback(null, iface_cache[key]); 234 | } else { 235 | 236 | bus.getInterface(serviceName, objectPath, interfaceName, function(err, iface) { 237 | if(err) { 238 | origCallback(err, null); 239 | } else { 240 | 241 | var signalKeys = Object.keys(iface.object.signal); 242 | var methodKeys = Object.keys(iface.object.method); 243 | var propertyKeys = Object.keys(iface.object.property); // generate getters for all properties 244 | //if(iface.object.method) console.log(iface.object.method); 245 | 246 | /* =========== Methods ===========*/ 247 | integrateMethods(valueToSet, iface, methodKeys); 248 | 249 | /* =========== Properties (getter and setter) ===========*/ 250 | integrateProperties(valueToSet, iface, propertyKeys); 251 | 252 | /* =========== Signals ===========*/ 253 | integrateSignals(valueToSet, iface, signalKeys); 254 | 255 | createCallback(null, valueToSet, function(err, iface) { 256 | if (!err) { 257 | iface_cache[key] = iface; 258 | } 259 | origCallback(err, iface); 260 | }); 261 | } 262 | }); 263 | } 264 | }; 265 | 266 | nm.disconnect = function (playerName, callback) { 267 | delete bus; 268 | }; 269 | 270 | var arrayOfBytesToString = function (ArrayOfBytes) { 271 | var SsidString = ""; // map D-Bus type "ab" (Array of bytes) to String 272 | ArrayOfBytes.forEach(function(code) { 273 | SsidString += String.fromCharCode(code); 274 | }); 275 | return SsidString; 276 | }; 277 | 278 | // undo arrayOfBytesToString 279 | var stringToArrayOfBytes = function (str) { 280 | var bytes = []; 281 | for (var i = 0; i < str.length; ++i) { 282 | bytes.push(str.charCodeAt(i)); 283 | } 284 | return bytes; 285 | }; 286 | 287 | // http://javascript.about.com/library/blipconvert.htm 288 | var numToIP = function (num) { 289 | var d = num%256; 290 | for (var i = 3; i > 0; i--) { 291 | num = Math.floor(num/256); 292 | d = d + '.' + num%256; 293 | } 294 | return d; 295 | } 296 | 297 | // undo numToIP 298 | var ipToNum = function (dot) { 299 | var d = dot.split('.'); 300 | return ((((((+d[3])*256)+(+d[2]))*256)+(+d[1]))*256)+(+d[0]); 301 | } 302 | 303 | 304 | // http://jsperf.com/convert-byte-array-to-hex-string 305 | var arrayOfBytesToMac = function (byteArrayData) { 306 | var ret = "", 307 | i = 0, 308 | len = byteArrayData.length; 309 | while (i < len) { 310 | var h = byteArrayData[i].toString(16); 311 | if (h.length < 2) { 312 | h = "0" + h; 313 | } 314 | ret += h.toUpperCase(); 315 | if(i+1 != len) 316 | ret += ":"; 317 | i++; 318 | } 319 | return ret; 320 | } 321 | 322 | // undo arrayOfBytesToMac 323 | function MacToArrayOfBytes(str) { 324 | var result = []; 325 | var hexArray = str.split(':'); 326 | hexArray.forEach(function(hex) { 327 | result.push(parseInt(hex, 16)); 328 | }); 329 | return result; 330 | } 331 | 332 | function ShortIPv6(value) { 333 | return value; 334 | } 335 | 336 | var arrayOfBytesToIPv6 = function (byteArrayData) { 337 | var ret = "", 338 | i = 0, 339 | len = byteArrayData.length; 340 | while (i < len) { 341 | var h = parseInt(byteArrayData[i]).toString(16); 342 | if (h.length < 2) { 343 | h = "0" + h; 344 | } 345 | ret += h; 346 | if(i%2 != 0 && i+1 != len) { // number odd and not last 347 | ret += ":"; 348 | } 349 | i++; 350 | } 351 | return ShortIPv6(ret); 352 | } 353 | 354 | // Addresses is Array of tuples of IPv4 address/prefix/gateway. 355 | // All 3 elements of each tuple are in network byte order. 356 | // Essentially: [(addr, prefix, gateway), (addr, prefix, gateway), ...] 357 | // See 358 | // https://developer.gnome.org/NetworkManager/0.9/spec.html#org.freedesktop.NetworkManager.IP4Config 359 | // https://github.com/rs/node-netmask 360 | var AddressTupleToIPBlock = function (AddressTuple) { 361 | 362 | var ip = numToIP(AddressTuple[0]); 363 | var bitmask = AddressTuple[1]; 364 | var gateway = numToIP(AddressTuple[2]); 365 | var block = new Netmask(ip, bitmask); 366 | block.ip = ip; 367 | block.gateway = gateway; 368 | return block; 369 | }; 370 | 371 | // undo AddressTupleToIPBlock 372 | var IPBlockToAddressTuple = function(IpBLock) { 373 | var ip = ipToNum(IpBLock.ip); 374 | var bitmask = IpBLock.bitmask; 375 | var gateway = ipToNum(IpBLock.gateway); 376 | return [ ip, bitmask, gateway ]; 377 | } 378 | 379 | var AddressTupleToIPv6Block = function (AddressTuple) { 380 | var result = []; 381 | for(var address in AddressTuple) { 382 | address = address.split(','); 383 | result.push(arrayOfBytesToIPv6(address)+"/"+AddressTuple[address]); 384 | } 385 | return result; 386 | }; 387 | 388 | // private helper to wrap dbus function to map dbus object paths to proxy objects 389 | generateDbusProxyFunction = function(dbusFunc, mapProxyObjectFunc) { 390 | var proxyFunc; 391 | 392 | if (dbusFunc) { 393 | proxyFunc = function (proxyCallback) { 394 | 395 | dbusFunc(function(error, paths) { 396 | if (error) { 397 | proxyCallback(error); 398 | 399 | } else { 400 | async.map(paths, function(path, mapCallback) { 401 | mapProxyObjectFunc(path, mapCallback); 402 | }, proxyCallback); 403 | } 404 | }); 405 | 406 | }; 407 | } 408 | 409 | return proxyFunc; 410 | } 411 | 412 | nm.connect = function (callback) { 413 | bus = DBus.getBus('system'); 414 | bus.interfaces = {}; //clear interface cache with each connect 415 | iface_cache = {}; 416 | nm.bus = bus; 417 | nm.dbus = DBus; 418 | nm.serviceName = 'org.freedesktop.NetworkManager'; 419 | nm.objectPath = '/org/freedesktop/NetworkManager'; 420 | 421 | nm.NewNetworkManager = function (objectPath, callback) { 422 | var interfaceName = 'org.freedesktop.NetworkManager'; 423 | if(objectPath == null) {objectPath = '/org/freedesktop/NetworkManager';} 424 | loadInterface(NetworkManager = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, NetworkManager, callback) { 425 | 426 | NetworkManager.objectPath = objectPath; 427 | 428 | // Overwrite functions that returns an object paths, so it returns the proxy object 429 | if (NetworkManager.GetAllDevices) { 430 | NetworkManager.GetAllDevices = generateDbusProxyFunction(NetworkManager.GetAllDevices, nm.NewDevice); 431 | } 432 | 433 | if (NetworkManager.AddAndActivateConnection) { 434 | var _AddAndActivateConnection = NetworkManager.AddAndActivateConnection; 435 | NetworkManager.AddAndActivateConnection = function (connectionOptions, device, connection, callback) { 436 | _AddAndActivateConnection(connectionOptions, device.objectPath, connection.objectPath, function (error, NewConnectionPath, ActiveConnection) { 437 | if(error) callback(error); 438 | else { 439 | // TODO proxy args 440 | callback(null, NewConnectionPath, ActiveConnection); 441 | } 442 | }); 443 | } 444 | } 445 | 446 | if (NetworkManager.GetActiveConnections) { 447 | var _GetActiveConnections = NetworkManager.GetActiveConnections; 448 | NetworkManager.GetActiveConnections = function (callback) { 449 | _GetActiveConnections(function (error, ActiveConnectionPaths) { 450 | if(error) { 451 | callback(error); 452 | } else { 453 | async.map(ActiveConnectionPaths, 454 | function iterator(ActiveConnectionPath, callback) { 455 | nm.NewActiveConnection(ActiveConnectionPath, callback); 456 | }, callback 457 | ); 458 | } 459 | }); 460 | } 461 | } 462 | 463 | if (NetworkManager.GetState) { 464 | var _GetState = NetworkManager.GetState; 465 | NetworkManager.GetState = function (callback) { 466 | _GetState(function (error, StateCode) { 467 | if(error) callback(error); 468 | else { 469 | var StateObject = enums['NM_STATE'](StateCode); 470 | callback(null, StateObject); 471 | } 472 | }); 473 | } 474 | } 475 | 476 | if (NetworkManager.GetPrimaryConnection) { 477 | var _GetPrimaryConnection = NetworkManager.GetPrimaryConnection; 478 | NetworkManager.GetPrimaryConnection = function (callback) { 479 | _GetPrimaryConnection(function (error, PrimaryConnectionPath) { 480 | if(error) callback(error); 481 | else if (PrimaryConnectionPath == '/') callback(null, null); 482 | else nm.NewActiveConnection(PrimaryConnectionPath, callback); 483 | }); 484 | } 485 | } 486 | 487 | if (NetworkManager.GetActivatingConnection) { 488 | var _GetActivatingConnection = NetworkManager.GetActivatingConnection; 489 | NetworkManager.GetActivatingConnection = function (callback) { 490 | _GetActivatingConnection(function (error, ActivatingConnectionPath) { 491 | if(error) callback(error); 492 | else if (ActivatingConnectionPath == '/') callback(null, null); 493 | else { 494 | nm.NewActiveConnection(ActivatingConnectionPath, callback); 495 | } 496 | }); 497 | } 498 | } 499 | 500 | callback(error, NetworkManager); 501 | }); 502 | } 503 | 504 | nm.NewAccessPoint = function (objectPath, callback) { 505 | var interfaceName = 'org.freedesktop.NetworkManager.AccessPoint'; 506 | loadInterface(AccessPoint = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, AccessPoint, callback) { 507 | 508 | if (error) { 509 | console.error('NewAccessPoint error', objectPath, error, error.stack); 510 | callback(error); 511 | return; 512 | } 513 | 514 | AccessPoint.objectPath = objectPath; 515 | 516 | // Overwrite AccessPoint.GetSsid function to get Wireless SSID as strings instead of byte sequences. 517 | if (AccessPoint.GetSsid) { 518 | var _GetSsid = AccessPoint.GetSsid; 519 | AccessPoint.GetSsid = function (callback) { 520 | _GetSsid(function(error, Ssid) { 521 | var SsidString = null; 522 | if(!error) { 523 | SsidString = arrayOfBytesToString(Ssid); 524 | } 525 | callback(error, SsidString); 526 | }); 527 | } 528 | } 529 | 530 | if (AccessPoint.GetFlags) { 531 | var _GetFlags = AccessPoint.GetFlags; 532 | AccessPoint.GetFlags = function (callback) { 533 | _GetFlags(function(error, Flags) { 534 | if(!error) { 535 | Flags = enums['NM_802_11_AP_FLAGS'](Flags); 536 | } 537 | callback(error, Flags); 538 | }); 539 | } 540 | } 541 | 542 | if (AccessPoint.GetWpaFlags) { 543 | var _GetWpaFlags = AccessPoint.GetWpaFlags; 544 | AccessPoint.GetWpaFlags = function (callback) { 545 | _GetWpaFlags(function(error, WpaFlags) { 546 | if(!error) { 547 | WpaFlags = enums['NM_802_11_AP_SEC'](WpaFlags); 548 | } 549 | callback(error, WpaFlags); 550 | }); 551 | } 552 | } 553 | 554 | if (AccessPoint.GetRsnFlags) { 555 | var _GetRsnFlags = AccessPoint.GetRsnFlags; 556 | AccessPoint.GetRsnFlags = function (callback) { 557 | _GetRsnFlags(function(error, RsnFlags) { 558 | if(!error) { 559 | RsnFlags = enums['NM_802_11_AP_SEC'](RsnFlags); 560 | } 561 | callback(error, RsnFlags); 562 | }); 563 | } 564 | } 565 | 566 | if (AccessPoint.GetMode) { 567 | var _GetMode = AccessPoint.GetMode 568 | AccessPoint.GetMode = function (callback) { 569 | _GetMode(function (error, Mode) { 570 | Mode = enums['NM_802_11_MODE'](Mode, "access point"); 571 | callback(error, Mode); 572 | }); 573 | } 574 | } 575 | 576 | if (AccessPoint.GetAllProperties) { 577 | var _GetAllProperties = AccessPoint.GetAllProperties; 578 | AccessPoint.GetAllProperties = function (callback) { 579 | _GetAllProperties(function (error, props) { 580 | if (!error) { 581 | props.RsnFlags = enums['NM_802_11_AP_SEC'](props.RsnFlags); 582 | props.Ssid = arrayOfBytesToString(props.Ssid); 583 | props.Mode = enums['NM_802_11_MODE'](props.Mode, "access point"); 584 | } 585 | callback(error, props); 586 | }); 587 | } 588 | } 589 | 590 | callback(error, AccessPoint); 591 | }); 592 | } 593 | 594 | nm.NewDevice = function (objectPath, callback) { 595 | var interfaceName = 'org.freedesktop.NetworkManager.Device'; 596 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 597 | 598 | Device.objectPath = objectPath; 599 | 600 | // Overwrite functions that returns an object paths, so it returns the proxy object 601 | if (Device.GetIp4Config) { 602 | var _GetIp4Config = Device.GetIp4Config; 603 | Device.GetIp4Config = function (callback) { 604 | _GetIp4Config(function (error, Ip4ConfigPath) { 605 | if(error) { 606 | callback(error); 607 | } else { 608 | if(Ip4ConfigPath == "/") callback(error, null); 609 | else nm.NewIP4Config(Ip4ConfigPath, callback); 610 | } 611 | }); 612 | } 613 | } 614 | if (Device.GetIp6Config) { 615 | var _GetIp6Config = Device.GetIp6Config; 616 | Device.GetIp6Config = function (callback) { 617 | _GetIp6Config(function (error, Ip6ConfigPath) { 618 | if(error) { 619 | callback(error); 620 | } else { 621 | if(Ip6ConfigPath == "/") callback(error, null); 622 | else nm.NewIP6Config(Ip6ConfigPath, callback); 623 | } 624 | }); 625 | } 626 | } 627 | if (Device.GetStateReason) { 628 | var _GetStateReason = Device.GetStateReason; 629 | Device.GetStateReason = function (callback) { 630 | _GetStateReason(function (error, StateReason) { 631 | if(error) { callback(error);} 632 | else { 633 | for (var State in StateReason) break; 634 | var Reason = StateReason[State]; 635 | State = enums['NM_DEVICE_STATE'](parseInt(State)); 636 | Reason = enums['NM_DEVICE_STATE_REASON'](parseInt(Reason)); 637 | callback(error, State, Reason); 638 | } 639 | }); 640 | } 641 | } 642 | if (Device.GetCapabilities) { 643 | var _GetCapabilities = Device.GetCapabilities; 644 | Device.GetCapabilities = function (callback) { 645 | _GetCapabilities(function (error, Capabilities) { 646 | if(error) { callback(error);} 647 | else { 648 | Capabilities = enums['NM_DEVICE_CAP'](Capabilities); 649 | callback(error, Capabilities); 650 | } 651 | }); 652 | } 653 | } 654 | if (Device.GetDeviceType) { 655 | var _GetDeviceType = Device.GetDeviceType; 656 | Device.GetDeviceType = function (callback) { 657 | _GetDeviceType(function (error, DeviceType) { 658 | if(error) { callback(error);} 659 | else { 660 | DeviceType = enums['NM_DEVICE_TYPE'](DeviceType); 661 | callback(error, DeviceType); 662 | } 663 | }); 664 | } 665 | } 666 | 667 | // Load additional device interface for device type 668 | Device.GetDeviceType(function(error, Type){ 669 | if(error) callback(error); 670 | else { 671 | var additionalInterface = null; 672 | switch(Type.name) { 673 | case 'ETHERNET': 674 | additionalInterface = 'NewDeviceWired'; 675 | break; 676 | case 'WIFI': 677 | additionalInterface = 'NewDeviceWireless'; 678 | break; 679 | case 'UNUSED1': 680 | break; 681 | case 'UNUSED2': 682 | break; 683 | case 'BT': 684 | additionalInterface = 'NewDeviceBluetooth'; 685 | break; 686 | case 'OLPC_MESH': 687 | additionalInterface = 'NewDeviceOlpcMesh'; 688 | break; 689 | case 'WIMAX': 690 | additionalInterface = 'NewDeviceWiMax'; 691 | break; 692 | case 'MODEM': 693 | additionalInterface = 'NewDeviceModem'; 694 | break; 695 | case 'INFINIBAND': 696 | additionalInterface = 'NewDeviceInfiniband'; 697 | break; 698 | case 'BOND': 699 | additionalInterface = 'NewDeviceBond'; 700 | break; 701 | case 'VLAN': 702 | additionalInterface = 'NewDeviceVlan'; 703 | break; 704 | case 'ADSL': 705 | additionalInterface = 'NewDeviceAdsl'; 706 | break; 707 | case 'BRIDGE': 708 | additionalInterface = 'NewDeviceBridge'; 709 | break; 710 | } 711 | if(additionalInterface != null) { 712 | nm[additionalInterface](objectPath, function (error, AdditionalDevice){ 713 | Device = extend(Device, AdditionalDevice); 714 | callback(error, Device); 715 | }); 716 | } else { 717 | callback(error, Device); 718 | } 719 | } 720 | }); 721 | }); 722 | } 723 | 724 | nm.NewDeviceWired = function (objectPath, callback) { 725 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Wired'; 726 | loadInterface(DeviceWired = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, DeviceWired, callback) { 727 | DeviceWired.objectPath = objectPath; 728 | callback(error, DeviceWired); 729 | }); 730 | } 731 | 732 | nm.NewDeviceWireless = function (objectPath, callback) { 733 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Wireless'; 734 | loadInterface(DeviceWired = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, DeviceWireless, callback) { 735 | 736 | DeviceWireless.objectPath = objectPath; 737 | 738 | // Overwrite functions that returns an object paths, so it returns the proxy object 739 | if (DeviceWireless.GetAllAccessPoints) { 740 | DeviceWireless.GetAllAccessPoints = generateDbusProxyFunction(DeviceWireless.GetAllAccessPoints, nm.NewAccessPoint); 741 | } 742 | 743 | if (DeviceWireless.GetAccessPoints) { 744 | var _GetAccessPoints = DeviceWireless.GetAccessPoints; 745 | DeviceWireless.GetAccessPoints = function (callback) { 746 | _GetAccessPoints(function (error, AccessPointPaths) { 747 | if(error) { 748 | callback(error); 749 | } else { 750 | async.map(AccessPointPaths, 751 | function iterator(AccessPointPath, callback) { 752 | nm.NewAccessPoint(AccessPointPath, callback); 753 | }, callback 754 | ); 755 | } 756 | }); 757 | } 758 | } 759 | 760 | if (DeviceWireless.GetWirelessCapabilities) { 761 | var _GetWirelessCapabilities = DeviceWireless.GetWirelessCapabilities; 762 | DeviceWireless.GetWirelessCapabilities = function (callback) { 763 | _GetWirelessCapabilities(function (error, WirelessCapabilities) { 764 | if(error) { 765 | callback(error); 766 | } else { 767 | WirelessCapabilities = enums['NM_802_11_DEVICE_CAP'](WirelessCapabilities); 768 | callback(error, WirelessCapabilities); 769 | } 770 | }); 771 | } 772 | } 773 | 774 | if (DeviceWireless.GetMode) { 775 | var _GetMode = DeviceWireless.GetMode 776 | DeviceWireless.GetMode = function (callback) { 777 | _GetMode(function (error, Mode) { 778 | if(error) { 779 | callback(error); 780 | } else { 781 | Mode = enums['NM_802_11_MODE'](Mode, "wireless device"); 782 | callback(error, Mode); 783 | } 784 | }); 785 | } 786 | } 787 | 788 | callback(error, DeviceWireless); 789 | }); 790 | } 791 | 792 | nm.NewDeviceBluetooth = function (objectPath, callback) { 793 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Bluetooth'; 794 | loadInterface(DeviceBluetooth = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, DeviceBluetooth, callback) { 795 | Device.objectPath = objectPath; 796 | callback(error, DeviceBluetooth); 797 | }); 798 | } 799 | 800 | nm.NewDeviceOlpcMesh = function (objectPath, callback) { 801 | var interfaceName = 'org.freedesktop.NetworkManager.Device.OlpcMesh'; 802 | loadInterface(DeviceOlpcMesh = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, DeviceOlpcMesh, callback) { 803 | Device.objectPath = objectPath; 804 | callback(error, DeviceOlpcMesh); 805 | }); 806 | } 807 | 808 | nm.NewDeviceWiMax = function (objectPath, callback) { 809 | var interfaceName = 'org.freedesktop.NetworkManager.Device.WiMax'; 810 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 811 | Device.objectPath = objectPath; 812 | callback(error, Device); 813 | }); 814 | } 815 | 816 | nm.NewDeviceModem = function (objectPath, callback) { 817 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Modem'; 818 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 819 | Device.objectPath = objectPath; 820 | callback(error, Device); 821 | }); 822 | } 823 | 824 | nm.NewDeviceInfiniband = function (objectPath, callback) { 825 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Infiniband'; 826 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 827 | Device.objectPath = objectPath; 828 | callback(error, Device); 829 | }); 830 | } 831 | 832 | nm.NewDeviceBond = function (objectPath, callback) { 833 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Bond'; 834 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 835 | Device.objectPath = objectPath; 836 | callback(error, Device); 837 | }); 838 | } 839 | 840 | nm.NewDeviceVlan = function (objectPath, callback) { 841 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Vlan'; 842 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 843 | Device.objectPath = objectPath; 844 | callback(error, Device); 845 | }); 846 | } 847 | 848 | nm.NewDeviceAdsl = function (objectPath, callback) { 849 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Adsl'; 850 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 851 | Device.objectPath = objectPath; 852 | callback(error, Device); 853 | }); 854 | } 855 | 856 | nm.NewDeviceBridge = function (objectPath, callback) { 857 | var interfaceName = 'org.freedesktop.NetworkManager.Device.Bridge'; 858 | loadInterface(Device = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Device, callback) { 859 | Device.objectPath = objectPath; 860 | callback(error, Device); 861 | }); 862 | } 863 | 864 | nm.NewIP4Config = function (objectPath, callback) { 865 | var interfaceName = 'org.freedesktop.NetworkManager.IP4Config'; 866 | loadInterface(IP4Config = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, IP4Config, callback) { 867 | 868 | IP4Config.objectPath = IP4Config; 869 | 870 | /* 871 | * Overwrite IP4Config.GetAddresses function to get IP addresses as strings of the form 1.2.3.4 instead of network byte ordered integers. 872 | */ 873 | if (IP4Config.GetAddresses) { 874 | var _GetAddresses = IP4Config.GetAddresses; 875 | IP4Config.GetAddresses = function (callback) { 876 | _GetAddresses(function (error, Addresses) { 877 | if(error) { 878 | callback(error); 879 | } else { 880 | var result = []; 881 | if(!error) { 882 | for (var i = 0; i < Addresses.length; i++) { 883 | var AddressTuple = Addresses[i]; 884 | var IPv4 = AddressTupleToIPBlock(AddressTuple); 885 | result.push(IPv4); 886 | }; 887 | } 888 | // result.AddressTuple = Addresses; 889 | callback(error, result); 890 | } 891 | }); 892 | } 893 | } 894 | if (IP4Config.GetNameservers) { 895 | var _GetNameservers = IP4Config.GetNameservers; 896 | IP4Config.GetNameservers = function (callback) { 897 | _GetNameservers(function (error, Nameservers) { 898 | var result = []; 899 | if(!error) { 900 | for (var i = 0; i < Nameservers.length; i++) { 901 | debug(Nameservers[i]); 902 | var Nameserver = numToIP(Nameservers[i]); 903 | result.push(Nameserver); 904 | }; 905 | } 906 | callback(error, result); 907 | }); 908 | } 909 | } 910 | 911 | callback(error, IP4Config); 912 | }); 913 | } 914 | 915 | nm.NewIP6Config = function (objectPath, callback) { 916 | var interfaceName = 'org.freedesktop.NetworkManager.IP6Config'; 917 | loadInterface(IP6Config = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, IP6Config, callback) { 918 | 919 | IP6Config.objectPath = objectPath; 920 | 921 | if (IP6Config.GetAddresses) { 922 | var _GetAddresses = IP6Config.GetAddresses; 923 | IP6Config.GetAddresses = function (callback) { 924 | _GetAddresses(function (error, Addresses) { 925 | var result = []; 926 | if(!error) { 927 | for (var i = 0; i < Addresses.length; i++) { 928 | var AddressTuple = Addresses[i]; 929 | var IPv6 = AddressTupleToIPv6Block(AddressTuple); 930 | result.push(IPv6); 931 | }; 932 | } 933 | callback(error, result); 934 | }); 935 | } 936 | } 937 | 938 | if (IP6Config.GetNameservers) { 939 | var _GetNameservers = IP6Config.GetNameservers; 940 | IP6Config.GetNameservers = function (callback) { 941 | _GetNameservers(function (error, Nameservers) { 942 | var result = []; 943 | if(!error) { 944 | for (var i = 0; i < Nameservers.length; i++) { 945 | var NameserversIPv6 = arrayOfBytesToIPv6(Nameservers[i]); 946 | result.push(NameserversIPv6); 947 | }; 948 | } 949 | callback(error, result); 950 | }); 951 | } 952 | } 953 | 954 | callback(error, IP6Config); 955 | }); 956 | } 957 | 958 | nm.NewDHCP4Config = function (objectPath, callback) { 959 | var interfaceName = 'org.freedesktop.NetworkManager.DHCP4Config'; 960 | loadInterface(DHCP4Config = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, DHCP4Config, callback) { 961 | 962 | DHCP4Config.objectPath = objectPath; 963 | 964 | callback(error, DHCP4Config); 965 | }); 966 | } 967 | 968 | nm.NewDHCP6Config = function (objectPath, callback) { 969 | var interfaceName = 'org.freedesktop.NetworkManager.DHCP6Config'; 970 | loadInterface(DHCP6Config = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, DHCP6Config, callback) { 971 | 972 | DHCP6Config.objectPath = objectPath; 973 | 974 | callback(error, DHCP6Config); 975 | }); 976 | } 977 | 978 | nm.NewSettings = function (objectPath, callback) { 979 | var interfaceName = 'org.freedesktop.NetworkManager.Settings'; 980 | if(objectPath == null) {objectPath = '/org/freedesktop/NetworkManager/Settings';} 981 | loadInterface(Settings = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, Settings, callback) { 982 | 983 | Settings.objectPath = objectPath; 984 | 985 | if (Settings.ListConnections) { 986 | Settings.ListConnections = generateDbusProxyFunction(Settings.ListConnections, nm.NewSettingsConnection); 987 | } 988 | 989 | callback(error, Settings); 990 | }); 991 | } 992 | 993 | nm.NewAgentManager = function(objectPath, callback) { 994 | var interfaceName = 'org.freedesktop.NetworkManager.AgentManager'; 995 | if (objectPath == null) { 996 | objectPath = '/org/freedesktop/NetworkManager/AgentManager'; 997 | } 998 | loadInterface(AgentManager = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, AgentManager, callback) { 999 | AgentManager.objectPath = objectPath; 1000 | callback(error, AgentManager); 1001 | }); 1002 | } 1003 | 1004 | nm.NewSettingsConnection = function (objectPath, callback) { 1005 | var interfaceName = 'org.freedesktop.NetworkManager.Settings.Connection'; 1006 | loadInterface(SettingsConnection = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, SettingsConnection, callback) { 1007 | 1008 | SettingsConnection.objectPath = objectPath; 1009 | 1010 | // Overwrite functions that returns an object paths, so it returns the proxy object 1011 | if (SettingsConnection.GetSettings) { 1012 | var transformSettingsForHuman = function (Settings) { 1013 | if(Settings['802-11-wireless']) { 1014 | // Settings['802-11-wireless'].ssidBytes = Settings['802-11-wireless'].ssid; 1015 | if(Settings['802-11-wireless'].ssid instanceof Array) 1016 | Settings['802-11-wireless'].ssid = arrayOfBytesToString(Settings['802-11-wireless'].ssid); 1017 | // Settings['802-11-wireless']['mac-address-bytes'] = Settings['802-11-wireless']['mac-address']; 1018 | if(Settings['802-11-wireless'].ssid instanceof Array) 1019 | Settings['802-11-wireless']['mac-address'] = arrayOfBytesToMac(Settings['802-11-wireless']['mac-address']); 1020 | } 1021 | if(Settings.ipv4) { 1022 | var addresses = []; 1023 | for (var i = 0; i < Settings.ipv4.addresses.length; i++) { 1024 | var AddressTuple = Settings.ipv4.addresses[i]; 1025 | var IPv4 = AddressTupleToIPBlock(AddressTuple); 1026 | addresses.push(IPv4); 1027 | }; 1028 | // Settings.ipv4.AddressTuple = Settings.ipv4.addresses; 1029 | Settings.ipv4.addresses = addresses; 1030 | 1031 | var nameservers = []; 1032 | for (var i = 0; i < Settings.ipv4.dns.length; i++) { 1033 | var nameserver = numToIP(Settings.ipv4.dns[i]); 1034 | nameservers.push(nameserver); 1035 | }; 1036 | Settings.ipv4.dns = nameservers; 1037 | } 1038 | return Settings; 1039 | } 1040 | var _GetSettings = SettingsConnection.GetSettings; 1041 | SettingsConnection.GetSettings = function (withSecrets, callback) { 1042 | _GetSettings(function (error, Settings) { 1043 | if(error) { 1044 | callback(error); 1045 | } else { 1046 | Settings = transformSettingsForHuman(Settings); 1047 | if(withSecrets) { 1048 | var hasSecrets = ['802-1x', '802-11-wireless-security', 'cdma', 'gsm', 'pppoe', 'vpn']; 1049 | async.each(hasSecrets, function( secretKey, callback) { 1050 | if(Settings[secretKey]) { 1051 | SettingsConnection.GetSecrets(secretKey, function(error, Secrets) { 1052 | if(!error && Secrets) { 1053 | Settings = extend(true, Settings, Secrets); 1054 | } 1055 | callback(); // ignore errors 1056 | }); 1057 | } else { 1058 | callback(); // ignore errors 1059 | } 1060 | }, function(error){ 1061 | callback(error, Settings); 1062 | }); 1063 | } else { 1064 | callback(null, Settings); 1065 | } 1066 | } 1067 | }); 1068 | } 1069 | } 1070 | 1071 | if (SettingsConnection.Update) { 1072 | var transformSettingsForDBus = function (Settings) { 1073 | if(Settings['802-11-wireless']) { 1074 | // TODO 1075 | if(typeof Settings['802-11-wireless'].ssid === "string") 1076 | Settings['802-11-wireless'].ssid = stringToArrayOfBytes(Settings['802-11-wireless'].ssid); 1077 | if(typeof Settings['802-11-wireless']['mac-address'] === "string") 1078 | Settings['802-11-wireless']['mac-address'] = MacToArrayOfBytes(Settings['802-11-wireless']['mac-address']); 1079 | } 1080 | if(Settings.ipv4) { 1081 | // Adresses 1082 | var addresses = []; 1083 | for (var i = 0; i < Settings.ipv4.addresses.length; i++) { 1084 | var IPBlock = Settings.ipv4.addresses[i]; 1085 | var AddressTuple = IPBlockToAddressTuple(IPBlock); 1086 | addresses.push(AddressTuple); 1087 | }; 1088 | Settings.ipv4.addresses = addresses; 1089 | 1090 | // Nameservers 1091 | var nameservers = []; 1092 | for (var i = 0; i < Settings.ipv4.dns.length; i++) { 1093 | var nameserver = ipToNum(Settings.ipv4.dns[i]); 1094 | nameservers.push(nameserver); 1095 | }; 1096 | Settings.ipv4.dns = nameservers; 1097 | } 1098 | return Settings; 1099 | } 1100 | 1101 | // TODO 1102 | // var _Update = SettingsConnection.Update; 1103 | // SettingsConnection.Update = function (Settings, callback) { 1104 | // Settings = transformSettingsForDBus(Settings); 1105 | // _Update(Settings, function (error) { 1106 | // callback(error, Settings); 1107 | // }); 1108 | // } 1109 | 1110 | // WORKAROUND 1111 | var updateWithPython = function (objectPath, settings, callback) { 1112 | settingsJsonString = JSON.stringify(settings); 1113 | var python = spawn('python', [__dirname+'/UpdateSettingsConnection.py', objectPath, settingsJsonString]); 1114 | python.on('exit', function(code, signal) { 1115 | callback(); 1116 | }); 1117 | python.stdout.on('data', function (data) { 1118 | console.log('stdout: ' + data); 1119 | }); 1120 | 1121 | python.stderr.on('data', function (data) { 1122 | console.log('stderr: ' + data); 1123 | }); 1124 | } 1125 | 1126 | // WORKAROUND 1127 | SettingsConnection.Update = function (Settings, callback) { 1128 | Settings = transformSettingsForDBus(Settings); 1129 | updateWithPython(objectPath, Settings, function() { 1130 | callback(null, Settings) 1131 | }); 1132 | } 1133 | } 1134 | 1135 | callback(error, SettingsConnection); 1136 | }); 1137 | } 1138 | 1139 | nm.NewActiveConnection = function (objectPath, callback) { 1140 | var interfaceName = 'org.freedesktop.NetworkManager.Connection.Active'; 1141 | loadInterface(ActiveConnection = {}, nm.serviceName, objectPath, interfaceName, callback, function (error, ActiveConnection, callback) { 1142 | 1143 | ActiveConnection.objectPath = objectPath; 1144 | 1145 | // Overwrite functions that returns an object paths, so it returns the proxy object 1146 | if (ActiveConnection.GetSpecificObject) { 1147 | ActiveConnection.GetSpecificObjectPath = ActiveConnection.GetSpecificObject; 1148 | ActiveConnection.GetSpecificObject = function (callback) { 1149 | ActiveConnection.GetSpecificObjectPath(function (error, SpecificObjectPath) { 1150 | if(error) callback(error); 1151 | else if(SpecificObjectPath == "/") callback(null, null); 1152 | else { 1153 | // if SpecificObjectPath has "AccessPoint" as substring 1154 | if(SpecificObjectPath.indexOf("AccessPoint") > -1) { 1155 | nm.NewAccessPoint(SpecificObjectPath, callback); 1156 | } else { 1157 | warn('SpecificObjectPath: "'+SpecificObjectPath+'" not yet implemented, please create an issue: https://github.com/JumpLink/node-networkmanager/issues'); 1158 | callback(null, null); 1159 | } 1160 | } 1161 | }); 1162 | } 1163 | } 1164 | 1165 | if (ActiveConnection.GetDevices) { 1166 | var _GetDevices = ActiveConnection.GetDevices; 1167 | ActiveConnection.GetDevices = function (callback) { 1168 | _GetDevices(function (error, DevicesPaths) { 1169 | if(error) { 1170 | callback(error); 1171 | } else { 1172 | async.map(DevicesPaths, 1173 | function iterator(DevicesPath, callback) { 1174 | if(DevicesPath == "/") callback(null, null); 1175 | else nm.NewDevice(DevicesPath, callback); 1176 | }, callback 1177 | ); 1178 | } 1179 | }); 1180 | } 1181 | } 1182 | 1183 | if (ActiveConnection.GetConnection) { 1184 | var _GetConnection = ActiveConnection.GetConnection; 1185 | ActiveConnection.GetConnection = function (callback) { 1186 | _GetConnection(function (error, SettingsConnectionPath) { 1187 | if(error) callback(error); 1188 | else if(SettingsConnectionPath == "/") callback(null, null); 1189 | else nm.NewSettingsConnection(SettingsConnectionPath, callback); 1190 | }); 1191 | } 1192 | } 1193 | 1194 | if (ActiveConnection.GetState) { 1195 | var _GetState = ActiveConnection.GetState; 1196 | ActiveConnection.GetState = function (callback) { 1197 | _GetState(function (error, State) { 1198 | if(error) callback(error); 1199 | else { 1200 | State = enums['NM_ACTIVE_CONNECTION_STATE'](State); 1201 | callback(null, State); 1202 | } 1203 | }); 1204 | } 1205 | } 1206 | 1207 | callback(error, ActiveConnection); 1208 | }); 1209 | } 1210 | 1211 | 1212 | waitForService(nm.serviceName, TIMEOUTDELAY, INTERVALDELAY, function (error) { 1213 | if (error) { 1214 | callback(error); 1215 | } else { 1216 | debug("NetworkManager DBus found! :)"); 1217 | nm.NewNetworkManager(null, function(error, NetworkManager) { 1218 | nm.NetworkManager = NetworkManager; 1219 | callback(error, nm); 1220 | }); 1221 | } 1222 | }); 1223 | } 1224 | 1225 | module.exports = nm; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-networkmanager", 3 | "version": "0.0.0", 4 | "description": "Controll the NetworkManager with Node.js", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Pascal Garber (http://jumplink.eu/)", 10 | "license": "MIT", 11 | "dependencies": { 12 | "async": "^0.9.0", 13 | "dbus": "^1.0.0", 14 | "debug": ">=2.6.9", 15 | "netmask": "^1.0.4", 16 | "node.extend": "^1.0.10" 17 | } 18 | } 19 | --------------------------------------------------------------------------------