From 618b7a4b2bd80bcca4173a6b98fb584bc8d5ccbf Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 17 Nov 2016 15:54:39 -0600 Subject: feat: add annex-client call_home support --- recipes-core/annex-client/annex-client-from-src.bb | 1 + recipes-core/annex-client/annex-client.bb | 32 +++- recipes-core/annex-client/annex-client/call_home | 192 +++++++++++++++++++++ .../annex-client/annex-client/call_home.init | 40 +++++ .../annex-client/annex-client/config.json.sample | 10 ++ .../annex-client/annex-client/monitor-annexcd | 46 +++++ .../annex-client/push_api_mdm_connected | 59 +++++++ .../annex-client/annex-client/push_api_mdm_status | 30 ++++ 8 files changed, 406 insertions(+), 4 deletions(-) create mode 100755 recipes-core/annex-client/annex-client/call_home create mode 100755 recipes-core/annex-client/annex-client/call_home.init create mode 100644 recipes-core/annex-client/annex-client/config.json.sample create mode 100755 recipes-core/annex-client/annex-client/monitor-annexcd create mode 100755 recipes-core/annex-client/annex-client/push_api_mdm_connected create mode 100755 recipes-core/annex-client/annex-client/push_api_mdm_status (limited to 'recipes-core') diff --git a/recipes-core/annex-client/annex-client-from-src.bb b/recipes-core/annex-client/annex-client-from-src.bb index a45e119..3534f23 100644 --- a/recipes-core/annex-client/annex-client-from-src.bb +++ b/recipes-core/annex-client/annex-client-from-src.bb @@ -5,6 +5,7 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda PROVIDES = "annex-client-from-src" DEPENDS = "jsoncpp curl protobuf cyrus-sasl protobuf-native annex-proto mts-io" +# IMPORTANT: if you change PR, you'll also want to change the url in annex-client.bb PR = "r1" SRCREV = "b954c83e155f95ecd68c14a890f9455331e19878" diff --git a/recipes-core/annex-client/annex-client.bb b/recipes-core/annex-client/annex-client.bb index 1a0544a..cf7ed5c 100644 --- a/recipes-core/annex-client/annex-client.bb +++ b/recipes-core/annex-client/annex-client.bb @@ -6,13 +6,20 @@ PROVIDES = "annex-client" # NOTE: annex-client binary is built with Jenkin's job using annex-client-from-src.bb # To update this, manually copy ipk from Jenkin's job to .net/downloads/ -PR = "r0" -SRC_URI = "http://multitech.net/downloads/annex-client-from-src_${PV}-${PR}.0_${TUNE_PKGARCH}.ipk \ +PR = "r2" +ANNEX_PR = "r1" +SRC_URI = "http://multitech.net/downloads/annex-client-from-src_1.0-${ANNEX_PR}.0_${TUNE_PKGARCH}.ipk \ file://annex-client.init \ + file://monitor-annexcd \ + file://call_home \ + file://call_home.init \ + file://config.json.sample \ + file://push_api_mdm_connected \ + file://push_api_mdm_status \ " -SRC_URI[md5sum] = "b17462ba3883df6a06b226b37a523eba" -SRC_URI[sha256sum] = "be903e7e27ad34832cb8045ef805f4e226aa6e254a3c995c5e61a0a9197a95b0" +SRC_URI[md5sum] = "e180f4e569fbba2f5b9d524b5a9e944e" +SRC_URI[sha256sum] = "1e93c65005c630cf211615dc143eb64f177591efcdbed6952142c7bac0e95988" #inherit update-rc.d # @@ -20,10 +27,27 @@ SRC_URI[sha256sum] = "be903e7e27ad34832cb8045ef805f4e226aa6e254a3c995c5e61a0a919 #INITSCRIPT_PARAMS = "defaults 95 1" S = "${WORKDIR}" +DHQ_DIR="/opt/devicehq" + do_install() { install -d ${D}${sbindir} install -m 755 sbin/annexcd ${D}${sbindir} + install -d ${D}/etc/ssl/certs + install -m 644 etc/ssl/certs/rootCA.pem ${D}/etc/ssl/certs + + install -d ${D}${base_sbindir} + install -m 755 ${WORKDIR}/monitor-annexcd ${D}${base_sbindir} + install -m 755 ${WORKDIR}/call_home ${D}${base_sbindir} + install -m 755 ${WORKDIR}/push_api_mdm_connected ${D}${base_sbindir} + install -m 755 ${WORKDIR}/push_api_mdm_status ${D}${base_sbindir} + install -d ${D}${sysconfdir}/init.d install -m 755 ${WORKDIR}/annex-client.init ${D}${sysconfdir}/init.d/annex-client + install -m 755 ${WORKDIR}/call_home.init ${D}${sysconfdir}/init.d/call_home + + install -d ${D}${DHQ_DIR} + install -m 644 ${WORKDIR}/config.json.sample ${D}${DHQ_DIR} } + +FILES_${PN} += "${DHQ_DIR}" diff --git a/recipes-core/annex-client/annex-client/call_home b/recipes-core/annex-client/annex-client/call_home new file mode 100755 index 0000000..64887ec --- /dev/null +++ b/recipes-core/annex-client/annex-client/call_home @@ -0,0 +1,192 @@ +#!/bin/bash +#Attempt to gain a WAN connection for MDM Registration to query for this device's MDM account ID +#PREREQ: Firewall allows outgoing DHCP requests and MDM Client connection + +CONFIG_FILE="/var/config/devicehq/config.json" +STATUS_FILE="/var/config/devicehq/status.json" + +if [ ! -f $CONFIG_FILE ]; then + logger -t callhome "Config file missing!" + logger -t callhome "Do: mkdir /var/config/devicehq" + logger -t callhome "Then: cp /opt/devicehq/config.json.sample /var/config/devicehq/config.json" + exit 1 +fi + +JSON=$(cat $CONFIG_FILE) +ENABLED=$( echo $JSON | jsparser -p /enabled ) +KEY=$( echo $JSON | jsparser -p /accountKey ) +MDM_URL=$( echo $JSON | jsparser -p /deviceHqUrl ) + +if [ "$ENABLED" != "true" ]; then + logger -t callhome "Not calling home because DeviceHQ is disabled in /var/config/devicehq/config..json." + exit 1 +fi + +UUID=$(mts-io-sysfs show uuid) +DEVID=$(mts-io-sysfs show device-id) + + +MDM_REG_URL="$MDM_URL/api/v1/register-device" +TMPFILE="/var/run/callhome" +DONE=false +FORCE=false +WAN_AVAILABLE=true +MAX_ATTEMPTS=0 #Infinite +INTERVAL_SECONDS=30 + +#Gather options from command line +# Reset in case getopts has been used previously in the shell. +OPTIND=1 + +function show_help() { + echo "Usage: $0 -k -a -i " +} + +while getopts "h?k:a:i:d:u:m:f" opt; do + case "$opt" in + h|\?) + show_help + exit 0 + ;; + k) KEY=$OPTARG + ;; + a) MAX_ATTEMPTS=$OPTARG + ;; + a) INTERVAL_SECONDS=$OPTARG + ;; + f) FORCE=true + ;; + d) DEVID=$OPTARG + ;; + u) UUID=$OPTARG + ;; + m) MDM_URL=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) + +[ "$1" = "--" ] && shift + +if [ "$FORCE" == "true" ]; then + DONE=false +fi + + +function checkCallHomeNeeded() { + if [ "$FORCE" != "true" ]; then + JSON=$(cat $CONFIG_FILE) + KEY=$( echo $JSON | jsparser -p /accountKey ) + + LAST_CONNECTED="unknown" + STATUS="" + if [ -f $STATUS_FILE ]; then + JSON=$(cat $STATUS_FILE) + LAST_CONNECTED=$( echo $JSON | jsparser -p /lastConnected ) + STATUS=$( echo $JSON | jsparser -p /status ) + fi + + if [ "$KEY" != "" ] && [ $LAST_CONNECTED != "unknown" ] && [ $STATUS == "idle" ]; then + echo "Found that Call-Home Not Needed" + exit 0 + fi + fi +} + +function saveConfigs() { + logger -t callhome "Saving accountKey" + + sed -i "s/\"accountKey\"\s*:\s*\".*\"/\"accountKey\": \"$KEY\"/" $CONFIG_FILE + + if [ $? != 0 ]; then + logger -t callhome "Failed to add account key [$KEY] to $CONFIG_FILE" + fi +} + +function checkForCheckIn() { + + i=0 + while [ $i -lt 10 ]; do + if [ -f $STATUS_FILE ]; then + JSON=$(cat $STATUS_FILE) + LAST_CONNECTED=$( echo $JSON | jsparser -p /lastConnected ) + STATUS=$( echo $JSON | jsparser -p /status ) + if [ "$LAST_CONNECTED" == "unknown" ] || [ $STATUS != "idle" ]; then + logger -t callhome "MDM client has not checked-in yet" + else + logger -t callhome "SUCCESS! MDM Client has checked-in." + DONE=true + return + fi + else + logger -t callhome "MDM client has not checked-in yet" + fi + + let i=i+1 + logger -t callhome "Sleeping for 30 seconds." + sleep 30 + done + +} + +function attemptMdmRegistration() { + + logger -t callhome "Attempting to register with MDM" + CODE=$( curl -m 20 -ks -o $TMPFILE -w "%{http_code}" -X POST -H "Content-Type: application/json" \ + -d '{ "device_id" : "'$DEVID'", "uuid" : "'$UUID'" }' \ + $MDM_REG_URL ) + + if [ $? == 0 ]; then + if [ "$CODE" == "200" ]; then + logger -t callhome "Registered with MDM. Checking for Account Key" + + #Request returned 200 + KEY=$( cat $TMPFILE | jsparser -p /account_key ) + if [ $? == 0 ]; then + if [ "$KEY" != "" ]; then + logger -t callhome "Received Account Key! [$KEY]" + saveConfigs + /etc/init.d/annex-client start + checkForCheckIn + else + logger -t callhome "Account Key not returned. This device may not be registered with a user account" + fi + else + RESULT=$(cat $TMPFILE) + logger -t callhome "Error: Unexpected MDM Registration Server response: $RESULT" + fi + else + RESULT=$(cat $TMPFILE) + logger -t callhome "Error: MDM Registration Failed with Device ID [$DEVID] and UUID [$UUID]" + logger -t callhome "Error: MDM Registration Server Response Header Code: $CODE" + logger -t callhome "Error: MDM Registration Server Response Body Content: $RESULT" + fi + else + logger -t callhome "Warning: Could not connect to MDM server: $MDM_REG_URL" + fi +} + +logger -t callhome "Setting Up Call-Home " +COUNT=0 + +while [ $DONE == false ]; do + logger -t callhome "Attempts: $COUNT" + + checkCallHomeNeeded + + attemptMdmRegistration + + COUNT=$(($COUNT+1)) + if [ $MAX_ATTEMPTS != 0 ] && [ $COUNT -gt $MAX_ATTEMPTS ]; then + DONE=true + logger -t callhome "Reached Maximum Attempts [$MAX_ATTEMPTS]" + fi + + if [ $DONE == false ]; then + logger -t callhome "Sleeping for $INTERVAL_SECONDS seconds before next attempt" + sleep $INTERVAL_SECONDS + fi + +done + diff --git a/recipes-core/annex-client/annex-client/call_home.init b/recipes-core/annex-client/annex-client/call_home.init new file mode 100755 index 0000000..b874565 --- /dev/null +++ b/recipes-core/annex-client/annex-client/call_home.init @@ -0,0 +1,40 @@ +#!/bin/bash +CALLHOME="/sbin/call_home" + +start() { + if [[ $(pidof $CALLHOME) ]]; then + echo "Call-Home Service is already running" + else + echo "Starting Call-Home Service" + $CALLHOME & + fi +} + +stop() { + CALLHOME_PID=$(pidof -x $CALLHOME) + if [[ $CALLHOME_PID ]]; then + echo "Stopping Call-Home Service" + kill $CALLHOME_PID + else + echo "Call-Home Service is not running" + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + *) + echo "Usage: /etc/init.d/call_home {start|stop|restart}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/recipes-core/annex-client/annex-client/config.json.sample b/recipes-core/annex-client/annex-client/config.json.sample new file mode 100644 index 0000000..c576a04 --- /dev/null +++ b/recipes-core/annex-client/annex-client/config.json.sample @@ -0,0 +1,10 @@ +{ + "enabled": false, + "accountKey": "", + "deviceHqUrl": "https://www.devicehq.com", + "deviceServerUrl": "ds.devicehq.com", + "checkInIntervalMins": 720, + "gpsDataIntervalMins": 720, + "allowFirmwareUpgrade": true, + "allowConfigUpgrade": true +} diff --git a/recipes-core/annex-client/annex-client/monitor-annexcd b/recipes-core/annex-client/annex-client/monitor-annexcd new file mode 100755 index 0000000..21d5a6b --- /dev/null +++ b/recipes-core/annex-client/annex-client/monitor-annexcd @@ -0,0 +1,46 @@ +#!/bin/bash + +CONFIG_FILE="/var/config/devicehq/config.json" + +if [ ! -f $CONFIG_FILE ]; then + logger -t monitor-annexcd "Config file missing!" + logger -t monitor-annexcd "Do: mkdir /var/config/devicehq" + logger -t monitor-annexcd "Then: cp /opt/devicehq/config.json.sample /var/config/devicehq/config.json" + logger -t monitor-annexcd "Exiting..." + exit 1 +fi + +DEVICE_ID=$(mts-io-sysfs show device-id) +PRODUCT_ID=$(mts-io-sysfs show product-id) + +get_args() { + JSON=$(cat $CONFIG_FILE) + + ENABLED=$( echo $JSON | jsparser -p enabled ) + KEY=$( echo $JSON | jsparser -p accountKey ) + SERVER=$( echo $JSON | jsparser -p deviceServerUrl ) + PORT=5798 + QUERY_INT=$( echo $JSON | jsparser -p checkInIntervalMins ) + GPS_INT=$( echo $JSON | jsparser -p gpsDataIntervalMins ) + FW_UPGRADE=$( echo $JSON | jsparser -p allowFirmwareUpgrade ) + CONFIG_UPGRADE=$(echo $JSON | jsparser -p allowConfigUpgrade ) +} + + +get_args + +if [ "$KEY" == "" ]; then + logger -t monitor-annexcd "Account key missing in $CONFIG_FILE" + logger -t monitor-annexcd "Exiting..." + exit 1 +fi + +MIN_TO_MS=60000 + +if [[ $ENABLED == "true" ]]; then + ANNEXCD="annexcd --account-key $KEY --host $SERVER --port $PORT --product-id $PRODUCT_ID --device-id $DEVICE_ID --rpd-interval $(( $QUERY_INT * $MIN_TO_MS )) --gps-interval $(( $GPS_INT * $MIN_TO_MS )) --net-interval $(( $QUERY_INT * $MIN_TO_MS )) --cell-interval $(( $QUERY_INT * $MIN_TO_MS )) --active-apps-interval $(( $QUERY_INT * $MIN_TO_MS )) --lora-interval $(( $QUERY_INT * $MIN_TO_MS )) --when-ppp-up on --firmware-upgrade $FW_UPGRADE --config-upgrade $CONFIG_UPGRADE --ssl-method ssl --ssl-ca-certificate /etc/ssl/certs/rootCA.pem --ssl-ca-strict --log-upto 7" + until $ANNEXCD; do + echo "annexcd exited with status $? - restarting..." >&2 + sleep 1 + done +fi diff --git a/recipes-core/annex-client/annex-client/push_api_mdm_connected b/recipes-core/annex-client/annex-client/push_api_mdm_connected new file mode 100755 index 0000000..ec8a23d --- /dev/null +++ b/recipes-core/annex-client/annex-client/push_api_mdm_connected @@ -0,0 +1,59 @@ +#!/bin/bash +# This script pushes the current time to the API's remote management +# to track last connected time + +STATUS_FILE="/var/config/devicehq/status.json" +DHQ_DIR="/var/config/devicehq" + +LAST_CONNECTED=$(date +%m/%d/%Y/%H:%M:%S) +INTERVAL="" + +# Reset in case getopts has been used previously in the shell. +OPTIND=1 + +function show_help() { + echo "Usage: $0 -t