diff --git a/libraries/AP_ONVIF/AP_ONVIF.cpp b/libraries/AP_ONVIF/AP_ONVIF.cpp index 6a0df5b1b1..8a4e5ebe55 100644 --- a/libraries/AP_ONVIF/AP_ONVIF.cpp +++ b/libraries/AP_ONVIF/AP_ONVIF.cpp @@ -22,23 +22,6 @@ // For ChibiOS we will use HW RND # generator #include //rand() - -#ifndef USERNAME -#define USERNAME "admin" -#endif - -#ifndef PASSWORD -#define PASSWORD "admin" -#endif - -#ifndef ONVIF_HOSTNAME -#define ONVIF_HOSTNAME "http://10.211.55.3:10000" -#endif - -#define DEVICE_ENDPOINT ONVIF_HOSTNAME"/onvif/device_service" -#define MEDIA_ENDPOINT ONVIF_HOSTNAME"/onvif/media_service" -#define PTZ_ENDPOINT ONVIF_HOSTNAME"/onvif/ptz_service" - #ifndef PRINT #define PRINT(fmt,args...) do {printf(fmt "\n", ## args); } while(0) #endif @@ -46,9 +29,18 @@ const char *wsse_PasswordDigestURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"; const char *wsse_Base64BinaryURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"; -// static AP _ONVIF *_singleton; +AP_ONVIF *AP_ONVIF::_singleton; extern const AP_HAL::HAL &hal; +// Default constructor +AP_ONVIF::AP_ONVIF() +{ + if (_singleton != nullptr) { + AP_HAL::panic("AP_ONVIF must be singleton"); + } + _singleton = this; +} + bool AP_ONVIF::init() { srand ((time_t)(hal.util->get_hw_rtc()/1000000ULL)); @@ -65,43 +57,29 @@ bool AP_ONVIF::init() AP_HAL::panic("AP_ONVIF: Failed to allocate gSOAP Proxy objects."); return false; } + return true; +} + +bool AP_ONVIF::start(const char *user, const char *pass, const char *httphostname) +{ + username = user; + password = pass; + hostname = httphostname; + + DEVICE_ENDPOINT = hostname + "/onvif/device_service"; + MEDIA_ENDPOINT = hostname + "/onvif/media_service"; + PTZ_ENDPOINT = hostname + "/onvif/ptz_service"; /// TODO: Need to find a way to store this in parameter system // or it could be just storage, we will see - proxy_device->soap_endpoint = DEVICE_ENDPOINT; + proxy_device->soap_endpoint = DEVICE_ENDPOINT.c_str(); if (!probe_onvif_server()) { PRINT("Failed to probe onvif server."); return false; } - if (!hal.scheduler->thread_create(FUNCTOR_BIND_MEMBER(&AP_ONVIF::update, void), "onvif", - 4096, AP_HAL::Scheduler::PRIORITY_IO, 0)) { - PRINT("Failed to create onvif thread"); - return false; - } return true; } -void AP_ONVIF::update() -{ - while(true) { - float pan = pan_norm; - float tilt = tilt_norm; - - // translate them into actual commands using cmd limits - pan = ((pan + 1) * (pan_tilt_limit_max.x - pan_tilt_limit_min.x)/2.0) + pan_tilt_limit_min.x; - tilt = ((tilt + 1) * (pan_tilt_limit_max.y - pan_tilt_limit_min.y)/2.0) + pan_tilt_limit_min.y; - PRINT("PAN: %f TILT: %f", pan, tilt); - // don't send the same request again - if (uint32_t(pan*100.0) != uint32_t(last_pan_cmd*100.0) || uint32_t(tilt*100.0) != uint32_t(last_tilt_cmd*100.0)) { - // actually send the command - set_absolutemove(pan, tilt, 0.0); - last_pan_cmd = pan; - last_tilt_cmd = tilt; - } - hal.scheduler->delay(100); - } -} - void AP_ONVIF::report_error() { PRINT("ONVIF ERROR:\n"); @@ -171,7 +149,7 @@ bool AP_ONVIF::probe_onvif_server() } // set the Media proxy endpoint to XAddr - proxy_media->soap_endpoint = MEDIA_ENDPOINT; + proxy_media->soap_endpoint = MEDIA_ENDPOINT.c_str(); // get device profiles _trt__GetProfiles GetProfiles; @@ -198,7 +176,7 @@ bool AP_ONVIF::probe_onvif_server() // Just use first one for now profile_token = GetProfilesResponse.Profiles[0]->token; - proxy_ptz->soap_endpoint = PTZ_ENDPOINT; + proxy_ptz->soap_endpoint = PTZ_ENDPOINT.c_str(); // _tptz__GetServiceCapabilities GetCapabilities; // _tptz__GetServiceCapabilitiesResponse GetCapabilitiesResponse; @@ -317,7 +295,7 @@ void AP_ONVIF::set_credentials() #else sha1_hash((const unsigned char*)nonce, 16, &ctx); sha1_hash((const unsigned char*)created, strlen(created), &ctx); - sha1_hash((const unsigned char*)PASSWORD, strlen(PASSWORD), &ctx); + sha1_hash((const unsigned char*)password.c_str(), strlen(password.c_str()), &ctx); nonceBase64 = (char*)base64_encode((unsigned char*)nonce, 16, &noncelen); #endif sha1_end((unsigned char*)HA, &ctx); @@ -331,7 +309,7 @@ void AP_ONVIF::set_credentials() memcpy(HABase64fin, HABase64enc, HABase64len); - if (soap_wsse_add_UsernameTokenText(soap, "Auth", USERNAME, HABase64fin)) { + if (soap_wsse_add_UsernameTokenText(soap, "Auth", username.c_str(), HABase64fin)) { report_error(); } /* populate the remainder of the password, nonce, and created */ diff --git a/libraries/AP_ONVIF/AP_ONVIF.h b/libraries/AP_ONVIF/AP_ONVIF.h index 39703aba71..9252a54c0d 100644 --- a/libraries/AP_ONVIF/AP_ONVIF.h +++ b/libraries/AP_ONVIF/AP_ONVIF.h @@ -25,24 +25,33 @@ class AP_ONVIF { public: + AP_ONVIF(); + + /* Do not allow copies */ + AP_ONVIF(const AP_ONVIF &other) = delete; + AP_ONVIF &operator=(const AP_ONVIF&) = delete; + bool init(); + bool start(const char *user, const char *pass, const char *httphostname); void set_credentials(); bool set_absolutemove(float pan, float tilt, float zoom); void set_pan_norm(float pan) { pan_norm = pan; } void set_tilt_norm(float tilt) { tilt_norm = tilt; } + void set_zoom_norm(float zoom) { zoom_norm = zoom; } + Vector2f get_pan_tilt_limit_max() const { return pan_tilt_limit_max; } + Vector2f get_pan_tilt_limit_min() const { return pan_tilt_limit_min; } // get singleton instance - // static AP_ONVIF *get_singleton() { return _singleton; } + static AP_ONVIF *get_singleton() { return _singleton; } private: void report_error(); bool probe_onvif_server(); void rand_nonce(char *nonce, size_t noncelen); - void update(); Vector2f pan_tilt_limit_min; Vector2f pan_tilt_limit_max; - float pan_norm, tilt_norm; + float pan_norm, tilt_norm, zoom_norm; float last_pan_cmd, last_tilt_cmd; float zoom_min, zoom_max; @@ -53,9 +62,17 @@ private: PTZBindingProxy *proxy_ptz; static AP_ONVIF *_singleton; char* media_endpoint; + + std::string username; + std::string password; + std::string hostname; + + std::string DEVICE_ENDPOINT; + std::string MEDIA_ENDPOINT; + std::string PTZ_ENDPOINT; }; -// namespace AP { -// AP_ONVIF *onvif(); -// }; + namespace AP { + AP_ONVIF &onvif(); + };