2020-06-13 07:28:50 +00:00
var os = require ( 'os' ) ;
var exec = require ( 'child_process' ) . exec ;
2020-12-16 17:28:16 +00:00
const onvif = require ( "shinobi-onvif" ) ;
2022-07-19 20:24:48 +00:00
const {
addCredentialsToUrl ,
} = require ( '../common.js' )
2020-06-13 07:28:50 +00:00
module . exports = function ( s , config , lang , app , io ) {
2021-10-18 05:04:21 +00:00
const {
createSnapshot ,
addCredentialsToStreamLink ,
} = require ( '../monitor/utils.js' ) ( s , config , lang )
2020-06-13 07:28:50 +00:00
const createOnvifDevice = async ( onvifAuth ) => {
var response = { ok : false }
const monitorConfig = s . group [ onvifAuth . ke ] . rawMonitorConfigurations [ onvifAuth . id ]
const controlBaseUrl = monitorConfig . details . control _base _url || s . buildMonitorUrl ( monitorConfig , true )
2020-06-13 18:04:38 +00:00
const controlURLOptions = s . cameraControlOptionsFromUrl ( controlBaseUrl , monitorConfig )
2020-06-13 07:28:50 +00:00
//create onvif connection
const device = new onvif . OnvifDevice ( {
2020-08-19 05:11:11 +00:00
address : controlURLOptions . host + ':' + controlURLOptions . port ,
2020-06-13 07:28:50 +00:00
user : controlURLOptions . username ,
pass : controlURLOptions . password
} )
s . group [ onvifAuth . ke ] . activeMonitors [ onvifAuth . id ] . onvifConnection = device
try {
const info = await device . init ( )
response . ok = true
2020-09-20 06:28:35 +00:00
response . device = device
2020-06-13 07:28:50 +00:00
} catch ( err ) {
response . msg = 'Device responded with an error'
2020-09-20 06:28:35 +00:00
response . error = err
2020-06-13 07:28:50 +00:00
}
return response
}
2020-09-20 06:28:35 +00:00
const replaceDynamicInOptions = ( Camera , options ) => {
const newOptions = { }
Object . keys ( options ) . forEach ( ( key ) => {
const value = options [ key ]
if ( typeof value === 'string' ) {
2021-09-13 15:03:35 +00:00
newOptions [ key ] = value . replace ( /__CURRENT_TOKEN/g , Camera . current _profile ? Camera . current _profile . token : 'NOTOKEN' )
2020-09-20 06:28:35 +00:00
} else if ( value !== undefined && value !== null ) {
newOptions [ key ] = value
}
} )
return newOptions
}
2020-09-20 17:45:10 +00:00
const runOnvifMethod = async ( onvifOptions , callback ) => {
2020-06-13 07:28:50 +00:00
var onvifAuth = onvifOptions . auth
var response = { ok : false }
var errorMessage = function ( msg , error ) {
response . ok = false
response . msg = msg
response . error = error
callback ( response )
}
var actionCallback = function ( onvifActionResponse ) {
response . ok = true
if ( onvifActionResponse . data ) {
response . responseFromDevice = onvifActionResponse . data
} else {
response . responseFromDevice = onvifActionResponse
}
if ( onvifActionResponse . soap ) response . soap = onvifActionResponse . soap
callback ( response )
}
var isEmpty = function ( obj ) {
for ( var key in obj ) {
if ( obj . hasOwnProperty ( key ) )
return false ;
}
return true ;
}
var doAction = function ( Camera ) {
var completeAction = function ( command ) {
if ( command && command . then ) {
command . then ( actionCallback ) . catch ( function ( error ) {
errorMessage ( 'Device Action responded with an error' , error )
} )
} else if ( command ) {
response . ok = true
response . repsonseFromDevice = command
callback ( response )
} else {
response . error = 'Big Errors, Please report it to Shinobi Development'
callback ( response )
}
}
var action
if ( onvifAuth . service ) {
if ( Camera . services [ onvifAuth . service ] === undefined ) {
return errorMessage ( 'This is not an available service. Please use one of the following : ' + Object . keys ( Camera . services ) . join ( ', ' ) )
}
if ( Camera . services [ onvifAuth . service ] === null ) {
return errorMessage ( 'This service is not activated. Maybe you are not connected through ONVIF. You can test by attempting to use the "Control" feature with ONVIF in Shinobi.' )
}
action = Camera . services [ onvifAuth . service ] [ onvifAuth . action ]
} else {
action = Camera [ onvifAuth . action ]
}
if ( ! action || typeof action !== 'function' ) {
errorMessage ( onvifAuth . action + ' is not an available ONVIF function. See https://github.com/futomi/node-onvif for functions.' )
} else {
var argNames = s . getFunctionParamNames ( action )
var options
var command
if ( argNames [ 0 ] === 'options' || argNames [ 0 ] === 'params' ) {
2020-09-20 06:28:35 +00:00
options = replaceDynamicInOptions ( Camera , onvifOptions . options || { } )
response . options = options
2020-06-13 07:28:50 +00:00
}
if ( onvifAuth . service ) {
command = Camera . services [ onvifAuth . service ] [ onvifAuth . action ] ( options )
} else {
command = Camera [ onvifAuth . action ] ( options )
}
completeAction ( command )
}
}
if ( ! s . group [ onvifAuth . ke ] . activeMonitors [ onvifAuth . id ] . onvifConnection ) {
2020-09-20 17:45:10 +00:00
const response = await createOnvifDevice ( onvifAuth )
2020-06-13 07:28:50 +00:00
if ( response . ok ) {
doAction ( response . device )
} else {
errorMessage ( response . msg , response . error )
}
} else {
doAction ( s . group [ onvifAuth . ke ] . activeMonitors [ onvifAuth . id ] . onvifConnection )
}
}
2021-10-18 05:04:21 +00:00
async function getSnapshotFromOnvif ( onvifOptions ) {
2021-12-05 03:11:18 +00:00
let theUrl ;
if ( onvifOptions . mid && onvifOptions . ke ) {
const groupKey = onvifOptions . ke
const monitorId = onvifOptions . mid
const theDevice = s . group [ groupKey ] . activeMonitors [ monitorId ] . onvifConnection
2022-07-19 20:24:48 +00:00
theUrl = addCredentialsToUrl ( {
username : onvifOptions . username ,
password : onvifOptions . password ,
url : ( await theDevice . services . media . getSnapshotUri ( {
ProfileToken : theDevice . current _profile . token ,
} ) ) . GetSnapshotUriResponse . MediaUri . Uri
} ) ;
2021-12-05 03:11:18 +00:00
} else {
theUrl = addCredentialsToStreamLink ( {
2021-10-18 05:04:21 +00:00
username : onvifOptions . username ,
password : onvifOptions . password ,
url : onvifOptions . uri
2021-12-05 03:11:18 +00:00
} )
}
return await createSnapshot ( {
output : [ '-s 400x400' ] ,
url : theUrl ,
2021-10-18 05:04:21 +00:00
} )
}
2020-06-13 07:28:50 +00:00
/ * *
* API : ONVIF Method Controller
* /
app . all ( [
config . webPaths . apiPrefix + ':auth/onvif/:ke/:id/:action' ,
config . webPaths . apiPrefix + ':auth/onvif/:ke/:id/:service/:action'
] , function ( req , res ) {
s . auth ( req . params , function ( user ) {
2020-09-20 06:28:35 +00:00
const options = s . getPostData ( req , 'options' , true ) || s . getPostData ( req , 'params' , true )
2020-06-13 07:28:50 +00:00
runOnvifMethod ( {
auth : {
ke : req . params . ke ,
id : req . params . id ,
action : req . params . action ,
service : req . params . service ,
} ,
2020-09-20 06:28:35 +00:00
options : options ,
2020-06-13 07:28:50 +00:00
} , ( endData ) => {
s . closeJsonResponse ( res , endData )
} )
} , res , req ) ;
} )
2021-10-18 05:04:21 +00:00
s . getSnapshotFromOnvif = getSnapshotFromOnvif
2020-06-13 07:28:50 +00:00
s . createOnvifDevice = createOnvifDevice
s . runOnvifMethod = runOnvifMethod
}