The Muzzley-Alljoyn Gateway Connector is an application that connects local AllJoyn networks with Muzzley Cloud services over MQTT. See http://allseenalliance.org for more information about AllJoyn, and http://muzzley.com for more information about Muzzley.
Normally an AllJoyn device can only communicate with other AllJoyn devices from within a local network. This application sends AllJoyn traffic over an MQTT connection to Muzzley cloud services, and announces Muzzley compatible AllJoyn devices over UPnP. This allows, for instance, a mobile phone running the Muzzley App to add those devices to the user's Muzzley account, and continue to communicate with those devices even when not connected to the local AllJoyn network via WiFi.
Building the source code requires first setting up dependencies and then using scons
to produce the binaries.
The following dependencies must be obtained and installed:
- libcap-dev
- libsoup-dev
- libxml2-dev
- libgupnp-1.0-dev
- libgssdp-1.0-dev
- libglib2.0-dev
- libssl-dev
- libcrypto-dev
- mosquitto-dev
- RapidJSON
- AllJoyn Gateway Agent
- AllJoyn Core
sudo apt-get install libcap-dev
sudo apt-get update
sudo apt-get install libxml2-dev
export LIBXML2_INCDIR = "/usr/include/libxml2"
export LIBXML2_LIBDIR = "/usr/lib"
sudo apt-get install libglib2.0-dev
export LIBGLIB_INCDIR = "/usr/include/glib-2.0"
export LIBGLIB_LIBDIR = "/usr/lib"
sudo apt-get install libsoup2.4-dev
export LIBSOUP_INCDIR = "/usr/include/libsoup-2.4"
sudo apt-get install libgupnp-1.0-dev
export LIBGUPNP_INCDIR = "/usr/include/gupnp-1.0"
sudo apt-get install libgssdp-1.0-dev
export LIBGSSDP_INCDIR = /usr/include/gssdp-1.0
It is necessary to download the RapidJSON source code (building is not necessary since the library is header-only).
Source code can be downloaded from https://github.com/miloyip/rapidjson.git.
After downloading, the RAPIDJSON_INCDIR environment variable must be defined before building muzzleyconn
.
For example, if your RapidJSON source code folder is RAPIDJSON_ROOT, then RAPIDJSON_INCDIR needs to point to $RAPIDJSON_ROOT/include:
export RAPIDJSON_INCDIR = $RAPIDJSON_ROOT/include
sudo apt-get install mosquitto-dev
export LIBMOSQUITTO_INCDIR = "/usr/include"
export LIBMOSQUITTO_LIBDIR = "/usr/lib"
-
Follow the instructions in here to set up your Ubuntu machine to build AllJoyn.
-
Create a new folder named "alljoyn-muzzley" on your home directory.
-
Use the "alljoyn-muzzley" folder as your workspace and create the following directory structure to setup your environment.
core/
gwagent/ (https://git.allseenalliance.org/gerrit/gateway/gwagent.git)
(git checkout RB14.12b)
ajtcl/ (https://git.allseenalliance.org/gerrit/core/ajtcl.git)
(git checkout RB14.12b)
alljoyn/ (https://git.allseenalliance.org/gerrit/core/alljoyn.git)
(git checkout RB14.12b)
base_tcl/ (https://git.allseenalliance.org/gerrit/services/base_tcl.git)
base/ (https://git.allseenalliance.org/gerrit/services/base.git)
(git checkout RB14.12b)
services/
base_tcl/ (https://git.allseenalliance.org/gerrit/services/base_tcl.git)
(git checkout RB14.12b)
base/ (https://git.allseenalliance.org/gerrit/services/base.git)
(git checkout RB14.12b)
-
Open a command terminal and from under the
core/gwagent/cpp
directory, clone this repository. -
Rename connector folder for a more friendly name like "MuzzleyConnector", and open the SConscript file under the
core/gwagent/cpp directory
, and add the same folder name to the arraygateway_dirs
. -
Export the following environment variables to setup your x86/64 build environment.
export TARGET_OS="linux"
export TARGET_CPU="x86_64"
export TARGET="x86_64-linux-gnu"
export VARIANT=debug
export AJ_ROOT="$HOME/alljoyn-muzzley"
export GWAGENT_SRC_DIR=$AJ_ROOT/core/gwagent
export ALLJOYN_DISTDIR=$GWAGENT_SRC_DIR/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/cpp/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/config/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/controlpanel/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/notification/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/services_common/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/cpp/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/config/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/controlpanel/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/notification/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/services_common/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/services_common/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/gatewayMgmtApp/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/gatewayController/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/gatewayConnector/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/$TARGET/lib/
export PATH=$PATH:/usr/$TARGET/bin
- Open a command terminal and from under the
core/alljoyn/
directory, run the commandscons
to build the core modules for x86_64 target.
scons V=1 OS=linux CPU=x86_64 BINDINGS="cpp" WS=off SERVICES="about,notification,controlpanel,config,onboarding,sample_apps"
- Open a command terminal and from under the
core/gwagent/
directory, run the commandscons
to build the gateway agent for x86_64 target.
scons V=1 OS=linux CPU=x86_64 BINDINGS="cpp" WS=off SERVICES="about,notification,controlpanel,config,onboarding,sample_apps"
- If needed, run the following
scons
command to clean the build files
scons V=1 OS=linux CPU=x86_64 BINDINGS="cpp" WS=off SERVICES="about,notification,controlpanel,config,onboarding,sample_apps" -c
- Next, set up the configuration file:
In the terminal navigate to the /etc/muzzleyconn
folder and then open the muzzleyconn\_factory.conf
file as superuser to edit it.
sudo gedit /etc/muzzleyconn/muzzleyconn_factory.conf
- These arguments can be optionally modified as needed:
Verbosity - level of debug output verbosity. Can be 0, 1, or 2, with 2 being the most verbose
The file looks like the following:
{
"ProductID": "muzzleyconn",
"SerialNumber": "muzzleyconn01",
"DeviceName" : "MuzzleyConnector",
"AppName" : "Muzzley MQTT Connector",
"Manufacturer" : "Muzzley",
"ModelNumber" : "MuzzleyConnector",
"Description" : "Muzzley AllJoyn MQTT connector",
"DateOfManufacture" : "2016-03-01",
"SoftwareVersion" : "0.0.1",
"HardwareVersion" : "0.0.1",
"SupportUrl" : "http://www.muzzley.com",
"Verbosity":"2",
"Server": "cloud-services.muzzley.com",
"Port": 5000
}
- Save and close the file. Now copy that file to
/etc/muzzleyconn/muzzleyconn.conf
as follows:
sudo cp /etc/muzzleyconn/muzzleyconn_factory.conf /etc/muzzleyconn/muzzleyconn.conf
- You are now ready to connect the
muzzleyconn
connector to the Muzzley cloud.
- Download the OpenWRT source code from:
git clone git://git.openwrt.org/14.07/openwrt.git
-
Download the config file for the correspondent hardware where OpenWRT will be run from here and paste it on the root of the openwrt project.
-
Copy downloaded config file to
.config
(for example):
cp config.ar71xx_generic .config
- Copy
feeds.conf.default
tofeeds.conf
(if not already done):
cp feeds.conf.default feeds.conf
- Add the following line to the end of the file:
src-git alljoyn https://git.allseenalliance.org/gerrit/core/openwrt_feed;barrier_breaker
- Update the feed information:
./scripts/feeds update -a
- Add the the packages from the feeds to build system (
luci
interface is not needed but recommended to configure the router using a web interface):
./scripts/feeds install -a -p alljoyn
./scripts/feeds install libgupnp
./scripts/feeds install libgssdp
./scripts/feeds install -a -p luci
- Enable AllJoyn in the build:
make menuconfig
Networking --->
< > alljoyn --->
< > alljoyn-about
< > alljoyn-c
< > alljoyn-config
< > alljoyn-config-samples
< > alljoyn-controlpanel
< > alljoyn-controlpanel-samples
< > alljoyn-notification
< > alljoyn-notification-samples
< > alljoyn-onboarding
< > alljoyn-onboarding-samples
< > alljoyn-sample_apps
< > alljoyn-samples
< > alljoyn-service_common
LuCI --->
< > Collections --->
< > luci
< > Themes --->
< > luci-themes-openwrt
Libraries --->
< > libxml2
< > libgupnp
< > libgssdp
< > mosquitto
- Make the firmware image including the correspondent configuration using the command:
make
- Flash it in the router firmware and wait for reboot.
- Export the following ambient variables to setup your OpenWRT build environment.
export TARGET_OS="openwrt"
export TARGET_CPU="openwrt"
export TARGET=mips-openwrt-linux-uclibc
export VARIANT=debug
export AJ_ROOT="$HOME/alljoyn-muzzley"
export AJ_DIST="$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/debug/dist"
export GWAGENT_SRC_DIR=$AJ_ROOT/core/gwagent
export ALLJOYN_DISTDIR=$GWAGENT_SRC_DIR/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist
export OPENWRT_BASE="$HOME/openwrt"
export OPENWRT_TOOLCHAIN_BASE=$OPENWRT_BASE/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/
export OPENWRT_TARGET_BASE=$OPENWRT_BASE/staging_dir/target-mips_34kc_uClibc-0.9.33.2/
export STAGING_DIR=$OPENWRT_BASE/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2
export PATH=$PATH:$OPENWRT_BASE/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/cpp/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/config/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/controlpanel/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/notification/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/alljoyn/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/services_common/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/cpp/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/config/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/controlpanel/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/notification/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/services_common/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/services_common/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/gatewayMgmtApp/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/gatewayController/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AJ_ROOT/core/gwagent/build/$TARGET_OS/$TARGET_CPU/$VARIANT/dist/gatewayConnector/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/$TARGET/lib/
export PATH=$PATH:/usr/$TARGET/bin
NOTE: Before building, make sure that TARGET
, RAPIDJSON\_INCDIR
, LIBGLIB_INCDIR
, LIBGLIB_LIBDIR
, MOSQUITTO_INCDIR
and MOSQUITTO_LIBDIR
are set appropriately, accordingly with your hardware architecture.
For ex.: mips-openwrt-linux-uclibc
The following commands are targeted for a mips-openwrt-linux-uclibc
hardware architecture. Some command changes may by needed for a different architecture.
- To compile the connector open a new terminal window under
~/alljoyn-muzzley/core/gwagent/
, and run the followingscons
compile command:
scons V=1 ICE=off BR=on BT=off WS=off CPU=openwrt OS=openwrt BINDINGS="cpp" SERVICES="about,notification,controlpanel,config,onboarding,sample_apps" TARGET_CFLAGS="-Os -pipe -mips32r2 -mtune=74kc -fPIC -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float" "TARGET_CC=$TARGET-gcc" "TARGET_CXX=$TARGET-g++" "TARGET_AR=$TARGET-ar" "TARGET_RANLIB=$TARGET-ranlib" "TARGET_LINK=$TARGET-gcc" "TARGET_CPPFLAGS=-I$OPENWRT_TARGET_BASE/usr/include -I$OPENWRT_TARGET_BASE/include -I$OPENWRT_TOOLCHAIN_BASE/usr/include -I$OPENWRT_TOOLCHAIN_BASE/include" "TARGET_PATH=$OPENWRT_TOOLCHAIN_BASE/bin:$OPENWRT_BASE/staging_dir/host/bin:$PATH" "STAGING_DIR=$OPENWRT_TARGET_BASE" "TARGET_LINKFLAGS=-L$OPENWRT_TARGET_BASE/usr/lib" "CXXFLAGS=$CXXFLAGS -I$AJ_DIST/cpp/inc -I$AJ_DIST/about/inc -I$AJ_DIST/services_common/inc -I$AJ_DIST/notification/inc -I$AJ_DIST/controlpanel/inc -I$AJ_DIST/services_common/inc" "LDFLAGS=$LDFLAGS -L$AJ_DIST/cpp/lib -L$AJ_DIST/about/lib -L$AJ_DIST/services_common/lib -L$AJ_DIST/notification/lib -L$AJ_DIST/controlpanel/lib"
- To clean the build environment, just add a
-c
at the end of the previous command.
scons V=1 ICE=off BR=on BT=off WS=off CPU=openwrt OS=openwrt BINDINGS="cpp" SERVICES="about,notification,controlpanel,config,onboarding,sample_apps" TARGET_CFLAGS="-Os -pipe -mips32r2 -mtune=74kc -fPIC -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float" "TARGET_CC=$TARGET-gcc" "TARGET_CXX=$TARGET-g++" "TARGET_AR=$TARGET-ar" "TARGET_RANLIB=$TARGET-ranlib" "TARGET_LINK=$TARGET-gcc" "TARGET_CPPFLAGS=-I$OPENWRT_TARGET_BASE/usr/include -I$OPENWRT_TARGET_BASE/include -I$OPENWRT_TOOLCHAIN_BASE/usr/include -I$OPENWRT_TOOLCHAIN_BASE/include" "TARGET_PATH=$OPENWRT_TOOLCHAIN_BASE/bin:$OPENWRT_BASE/staging_dir/host/bin:$PATH" "STAGING_DIR=$OPENWRT_TARGET_BASE" "TARGET_LINKFLAGS=-L$OPENWRT_TARGET_BASE/usr/lib" "CXXFLAGS=$CXXFLAGS -I$AJ_DIST/cpp/inc -I$AJ_DIST/about/inc -I$AJ_DIST/services_common/inc -I$AJ_DIST/notification/inc -I$AJ_DIST/controlpanel/inc -I$AJ_DIST/services_common/inc" "LDFLAGS=$LDFLAGS -L$AJ_DIST/cpp/lib -L$AJ_DIST/about/lib -L$AJ_DIST/services_common/lib -L$AJ_DIST/notification/lib -L$AJ_DIST/controlpanel/lib" -c
Note: An AllJoyn daemon must be running on the same local system for this program to work. Refer to http://wiki.allseenalliance.org/gateway/getting\_started to learn how to set up your system with the proper AllJoyn dependencies.
- You need to create a directory structure for the
muzzleyconn
app:
sudo mkdir -p /opt/alljoyn/apps/muzzleyconn/acls
sudo mkdir -p /opt/alljoyn/apps/muzzleyconn/bin
sudo mkdir -p /opt/alljoyn/apps/muzzleyconn/lib
sudo mkdir -p /opt/alljoyn/apps/muzzleyconn/store
sudo mkdir -p /opt/alljoyn/apps/muzzleyconn/etc
- Under Gateway Connector, the
muzzleyconn
process will be run as the "muzzleyconn" user. It needs to be able to write to theetc
subdirectory. Since we created the directory structure above as root (sudo), change the owner and the group of that directory:
sudo chown -R muzzleyconn /opt/alljoyn/apps/muzzleyconn
sudo chgrp -R muzzleyconn /opt/alljoyn/apps/muzzleyconn
- Copy the resulting executable, to the
bin
subdirectory ofmuzzleyconn
app:
sudo cp $ROOTPATH/muzzleyconn/build/muzzleyconn /opt/alljoyn/apps/muzzleyconn/bin
- Copy the Manifest file to the top-level muzzleyconn app directory:
sudo cp $ROOTPATH/muzzleyconn/Manifest.xml /opt/alljoyn/apps/muzzleyconn
- The Manifest file has to be modified to allow the
muzzleyconn
process to be run as the "muzzleyconn" user. Add the following line after the <env_variables> line:
<variable name="HOME">/home/muzzleyconn</variable>
- The Gateway Connector app needs a configuration file. Copy your
muzzleyconn_factory.conf
file to/opt/alljoyn/apps/muzzleyconn/etc/muzzleyconn_factory.conf
.
Note that the store
and acls
subdirectories will remain empty for now. You are now ready to execute muzzleyconn
as a Gateway Connector app.
NOTE: The actual implementation on the Muzzley Connector is not properly working as a Gateway Connector at this moment. Please skip this steps and follow the instructions bellow to run it as a standalone application. On the OpenWRT target, it is likely that the AllJoyn Gateway Agent starts automatically. In this case the Muzlzey connector process must be killed and started manually again.
- Start the Gateway Agent:
sudo service alljoyn-gwagent start
- Verify that it is running:
sudo service alljoyn-gwagent status
- Start the Gateway Agent:
alljoyn-gwagent
- Verify that it is running:
ps -ef | grep alljoyn-gateway
- The instructions for downloading and running the Gateway Connector Appplication on Android are on the AllSeen Alliance website.After installing the app, open it and click on AllJoyn Gateway Configuration Manager. You should see "AllJoyn Muzzley Connector" in the Gateway Connector Applications list. At this point, the state of the app should show "Stopped". This is because we haven't created any Access Control Lists (ACL's) yet.
-
Click on the "Muzzley" button to open the MQTT Connector app. Using the context menu on your Android device, click on "Create ACL". This will open up a window where you choose a name for your ACL, and choose which services will be allowed to pass through
muzzleyconn
. For now, select the "Expose all services" checkbox, since we want to ensure that themuzzleyconn
app works just as the command-linemuzzleyconn
. Click on "Create". -
Go back to the previous window (the Muzzley Connector app). You will see that it still shows up as "Stopped". First, you need to make sure that the newly created ACL is in the "Active" state. Then, from the Linux command line, restart the Gateway Agent, and verify the it is running.
NOTE: It is possible that the Gateway Agent is not running at this point (you might see the message "The process appears to be dead but pidfile still exists"). If this happens, you will need to restart the AllJoyn service, and then restart the Gateway Agent.
- The Gateway Agent should now be running.
-
When running as a normal AllJoyn application without the Gateaway Agent it is unnecessary for the gateway agent to be running. In this case just make sure the alljoyn-daemon is running.
-
If the instructions were followed according to the above Wiki article the daemon should already exist. It can be started as follows:
sudo service alljoyn start
- Then the
muzzleyconn
application can be run directly if desired.
./muzzleyconn
- Check the logs for any error.
- Start the Muzzley Connector, simply running it:
cd /opt/alljoyn/apps/muzzleyconn/bin
./muzzleyconn
- Check the logs for any error.
Copyright (c) 2016, Muzzley
Copyright (c) 2015, Affinegy, Inc.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.