sample code - “get/set device property, send command”¶
usage:
setdp <DP name> <param> [1-blocking,0-no blocking]
getdp <DP name>
infodp <DP name>
listdp
send <command name> <param>
setcc <control code> <param>
infocc <control code>
listcc
To exit, please enter 'q'.
argument |
example |
|---|---|
DP name |
FNumber for CrDeviceProperty_FNumber. |
command name |
Release for CrCommandId_Release. |
control code |
S1Button for CrControlCode_S1Button. |
param |
80, 0x50 (numeric value) |
This sample code is included in SimpleCli.
1// get/set deviceProperty, send command sample
2#include <chrono>
3#include <cinttypes>
4#include <codecvt>
5#include <cstdint>
6#include <cstdlib>
7#include <fstream>
8#include <future>
9#include <iostream>
10#include <mutex>
11#include <sstream>
12#include <stdexcept>
13#include <string>
14#include <thread>
15#include <vector>
16
17#if !defined(__APPLE__)
18 #if defined(USE_EXPERIMENTAL_FS) // for jetson
19 #include <experimental/filesystem>
20 namespace fs = std::experimental::filesystem;
21 #else
22 #include <filesystem>
23 namespace fs = std::filesystem;
24 #endif
25#endif
26
27#if defined(__APPLE__) || defined(__linux__)
28 #include <unistd.h>
29#endif
30
31#if defined(_WIN32) || defined(_WIN64)
32 using CrString = std::wstring;
33#else
34 using CrString = std::string;
35#endif
36
37// macro for multibyte character
38#if defined(_WIN32) || defined(_WIN64)
39 #define CRSTR(s) L ## s
40 #define CrCout std::wcout
41 #define Utf8ToCr(a) wstring_convert.from_bytes(a)
42 static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> wstring_convert;
43#else
44 #define CRSTR(s) s
45 #define CrCout std::cout
46 #define Utf8ToCr(a) (a)
47 static std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> wstring_convert;
48#endif
49
50
51#include "CrDeviceProperty.h"
52#include "CameraRemote_SDK.h"
53#include "IDeviceCallback.h"
54#include "CrDebugString.h" // use CrDebugString.cpp
55
56#define PrintError(msg, err) { fprintf(stderr, "Error in %s(%d):" msg ",%s\n", __FUNCTION__, __LINE__, (err ? CrErrorString(err).c_str():"")); }
57#define GotoError(msg, err) { PrintError(msg, err); goto Error; }
58
59bool m_connected = false;
60CrString m_modelId;
61int64_t m_device_handle = 0;
62bool m_lvProtocolChanged = false;
63
64std::mutex m_eventPromiseMutex;
65uint32_t m_setDPCode = 0;
66std::promise<void>* m_eventPromise = nullptr;
67void setEventPromise(std::promise<void>* dp)
68{
69 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
70 m_eventPromise = dp;
71}
72
73SCRSDK::CrError _getDeviceProperty(int64_t device_handle, uint32_t code, SCRSDK::CrDeviceProperty* devProp)
74{
75 std::int32_t nprop = 0;
76 SCRSDK::CrDeviceProperty* prop_list = nullptr;
77 SCRSDK::CrError err = SCRSDK::GetSelectDeviceProperties(device_handle, 1, &code, &prop_list, &nprop);
78 if(err) GotoError("", err);
79 if(prop_list && nprop >= 1) {
80 *devProp = prop_list[0];
81 }
82Error:
83 if(prop_list) SCRSDK::ReleaseDeviceProperties(device_handle, prop_list);
84 return err;
85}
86
87SCRSDK::CrError _setDeviceProperty(int64_t device_handle, uint32_t code, uint64_t data, bool blocking=true)
88{
89 int result = SCRSDK::CrError_Generic_Unknown;
90 SCRSDK::CrError err = 0;
91 std::promise<void> eventPromise;
92 std::future<void> eventFuture = eventPromise.get_future();
93 std::future_status status;
94
95 SCRSDK::CrDeviceProperty devProp;
96
97 err = _getDeviceProperty(device_handle, code, &devProp);
98 if(err) GotoError("", err);
99 if (devProp.GetValueType() == SCRSDK::CrDataType_STR) GotoError("STR is not supported", 0);
100 if (blocking && devProp.GetCurrentValue() == data) {
101 std::cout << "skipped\n";
102 return 0;
103 }
104
105 if(blocking) {
106 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
107 m_setDPCode = code;
108 m_eventPromise = &eventPromise;
109 }
110
111 devProp.SetCurrentValue(data);
112 err = SCRSDK::SetDeviceProperty(device_handle, &devProp);
113 if(err) GotoError("", err);
114
115 if(!blocking) return 0;
116
117 status = eventFuture.wait_for(std::chrono::milliseconds(3000));
118 if(status != std::future_status::ready) GotoError("timeout", 0);
119
120 try{
121 eventFuture.get();
122 } catch(const std::exception&) GotoError("", 0);
123 std::cout << "OK\n";
124
125 result = 0;
126Error:
127 setEventPromise(nullptr);
128 return result;
129}
130
131std::vector<int64_t> _getPossible(SCRSDK::CrDataType dataType, const uint8_t* values, uint32_t valueSize)
132{
133/*
134 CrInt32u GetSetValueSize();
135 CrInt8u* GetSetValues();
136*/
137 std::vector<int64_t> possible;
138
139 int dataLen = 1;
140 switch(dataType & 0x100F) {
141 case SCRSDK::CrDataType_UInt8: dataLen = sizeof(uint8_t); break;
142 case SCRSDK::CrDataType_Int8: dataLen = sizeof(int8_t); break;
143 case SCRSDK::CrDataType_UInt16: dataLen = sizeof(uint16_t); break;
144 case SCRSDK::CrDataType_Int16: dataLen = sizeof(int16_t); break;
145 case SCRSDK::CrDataType_UInt32: dataLen = sizeof(uint32_t); break;
146 case SCRSDK::CrDataType_Int32: dataLen = sizeof(int32_t); break;
147 case SCRSDK::CrDataType_UInt64: dataLen = sizeof(uint64_t); break;
148 default: return possible;
149 }
150
151 const uint8_t* buf = values;
152 uint32_t nval = valueSize / dataLen;
153 possible.resize(nval);
154 for (uint32_t i = 0; i < nval; ++i) {
155 int64_t data = 0;
156 switch(dataType & 0x100F) {
157 case SCRSDK::CrDataType_UInt8: data = (reinterpret_cast<uint8_t const*>(buf))[i]; break;
158 case SCRSDK::CrDataType_Int8: data = (reinterpret_cast<int8_t const*>(buf))[i]; break;
159 case SCRSDK::CrDataType_UInt16: data = (reinterpret_cast<uint16_t const*>(buf))[i]; break;
160 case SCRSDK::CrDataType_Int16: data = (reinterpret_cast<int16_t const*>(buf))[i]; break;
161 case SCRSDK::CrDataType_UInt32: data = (reinterpret_cast<uint32_t const*>(buf))[i]; break;
162 case SCRSDK::CrDataType_Int32: data = (reinterpret_cast<int32_t const*>(buf))[i]; break;
163 case SCRSDK::CrDataType_UInt64: data = (reinterpret_cast<uint64_t const*>(buf))[i]; break;
164 default: break;
165 }
166 possible.at(i) = data;
167 }
168 return possible;
169}
170
171CrString _getCurrentStr(SCRSDK::CrDeviceProperty* devProp)
172{
173 CrString current;
174 uint16_t* dp = devProp->GetCurrentStr();
175 if(!dp) GotoError("", 0);
176 if(*dp > 0) {
177 if(devProp->GetCode() == SCRSDK::CrDeviceProperty_ImageID_String) {
178 for(int i = 0; i < *dp; i++) {
179 uint16_t data = dp[1+i];
180 dp[1+i] = (data>>8) | (data<<8);
181 }
182 }
183 #if defined (_WIN32) || defined(_WIN64)
184 current = CrString((wchar_t*)(dp+1));
185 #else
186 int length = dp[0];
187 current = wstring_convert.to_bytes(std::u16string((dp+1), (dp+1)+length));
188 #endif
189 }
190Error:
191 return current;
192}
193
194class DeviceCallback : public SCRSDK::IDeviceCallback
195{
196public:
197 DeviceCallback() {};
198 ~DeviceCallback() {};
199
200 void OnConnected(SCRSDK::DeviceConnectionVersioin version)
201 {
202 CrCout << "Connected to " << m_modelId << "\n";
203 m_connected = true;
204 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
205 if(m_eventPromise) {
206 m_eventPromise->set_value();
207 m_eventPromise = nullptr;
208 }
209 }
210
211 void OnError(CrInt32u error)
212 {
213 printf("Connection error:%s\n", CrErrorString(error).c_str());
214 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
215 if(m_eventPromise) {
216 m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
217 m_eventPromise = nullptr;
218 }
219 }
220
221 void OnDisconnected(CrInt32u error)
222 {
223 CrCout << "Disconnected from " << m_modelId << "\n";
224 m_connected = false;
225 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
226 if(m_eventPromise) {
227 m_eventPromise->set_value();
228 m_eventPromise = nullptr;
229 }
230 }
231
232 void OnCompleteDownload(CrChar* filename, CrInt32u type )
233 {
234 CrCout << "OnCompleteDownload:" << filename << "\n";
235 }
236
237 void OnNotifyContentsTransfer(CrInt32u notify, SCRSDK::CrContentHandle contentHandle, CrChar* filename)
238 {
239 std::cout << "OnNotifyContentsTransfer.\n";
240 }
241
242 void OnWarning(CrInt32u warning)
243 {
244 if (warning == SCRSDK::CrWarning_Connect_Reconnecting) {
245 CrCout << "Reconnecting to " << m_modelId << "\n";
246 return;
247 }
248 if (warning == SCRSDK::CrNotify_LiveView_Alt_Ready) {
249 m_lvProtocolChanged = true;
250 }
251 std::cout << "OnWarning:" << CrErrorString(warning) << "\n";
252 }
253
254 void OnWarningExt(CrInt32u warning, CrInt32 param1, CrInt32 param2, CrInt32 param3)
255 {
256 std::cout << "OnWarningExt:" << CrWarningExtString(warning, param1, param2, param3).c_str() << "\n";
257 }
258
259 void OnLvPropertyChanged() {}
260 void OnLvPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
261 void OnPropertyChanged() {}
262 void OnPropertyChangedCodes(CrInt32u num, CrInt32u* codes)
263 {
264 std::cout << "OnPropertyChangedCodes:\n";
265 for(uint32_t i = 0; i < num; ++i) {
266 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
267 if(m_setDPCode && m_setDPCode == codes[i]) {
268 m_setDPCode = 0;
269 if(m_eventPromise) {
270 m_eventPromise->set_value();
271 m_eventPromise = nullptr;
272 }
273 }
274 std::string name = CrDevicePropertyString((SCRSDK::CrDevicePropertyCode)codes[i]);
275
276 SCRSDK::CrDeviceProperty devProp;
277 SCRSDK::CrError err = _getDeviceProperty(m_device_handle, codes[i], &devProp);
278 if(err) break;
279 if(devProp.GetValueType() == SCRSDK::CrDataType_STR) {
280 CrCout << " " << CrString(name.begin(), name.end()) << "=\"" << _getCurrentStr(&devProp) << "\"\n";
281 } else {
282 int64_t current = devProp.GetCurrentValue();
283 if(current < 10) {
284 printf(" %s=%" PRId64 "\n", name.c_str(), current);
285 } else {
286 printf(" %s=0x%" PRIx64 "(%" PRId64 ")\n", name.c_str(), current, current);
287 }
288 }
289 }
290 }
291};
292
293CrString _getModelId(const SCRSDK::ICrCameraObjectInfo* objInfo)
294{
295 CrString id;
296 if (CrString(objInfo->GetConnectionTypeName()) == CRSTR("IP")) {
297 id = CrString(objInfo->GetMACAddressChar());
298 } else {
299 id = CrString((CrChar*)objInfo->GetId());
300 }
301 return CrString(objInfo->GetModel()).append(CRSTR(" (")).append(id).append(CRSTR(")"));
302}
303
304SCRSDK::CrError _getIdPassword(SCRSDK::ICrCameraObjectInfo* objInfo, std::string& fingerprint, std::string& userId, std::string& userPassword)
305{
306 char fpBuff[128] = {0};
307 CrInt32u fpLen = 0;
308 SCRSDK::CrError err = SCRSDK::GetFingerprint(objInfo, fpBuff, &fpLen);
309 if(err) GotoError("", err);
310 fingerprint = std::string(fpBuff, fpLen);
311
312 std::cout << "fingerprint: " << fingerprint.c_str() << "\n";
313 std::cout << "id:"; std::getline(std::cin, userId);
314 std::cout << "password:"; std::getline(std::cin, userPassword);
315 return 0;
316Error:
317 return err;
318}
319
320std::vector<std::string> _split(std::string inputLine, char delimiter)
321{
322 std::vector<std::string> strArray;
323 if (inputLine.empty()) return strArray;
324
325 std::string tmp;
326 std::stringstream ss{inputLine};
327 while (getline(ss, tmp, delimiter)) {
328 strArray.push_back(tmp);
329 }
330 return strArray;
331}
332
333int64_t _stoll(std::string inputLine)
334{
335 int64_t data = 0;
336 if(inputLine.empty()) throw std::runtime_error("error");
337 try {
338 if (inputLine.compare(0, 2, "0x") == 0 || inputLine.compare(0, 2, "0X") == 0) {
339 data = std::stoull(inputLine.substr(2), nullptr, 16);
340 } else {
341 data = std::stoll(inputLine, nullptr, 10);
342 }
343 } catch(const std::exception& ex) {
344 throw ex;
345 }
346 return data;
347}
348
349int main(void)
350{
351 int result = -1;
352 SCRSDK::CrError err = SCRSDK::CrError_None;
353 SCRSDK::ICrEnumCameraObjectInfo* enumCameraObjectInfo = nullptr;
354 SCRSDK::ICrCameraObjectInfo* objInfo = nullptr;
355 DeviceCallback deviceCallback;
356
357 #if defined(__APPLE__)
358 #define MAC_MAX_PATH 255
359 char pathBuf[MAC_MAX_PATH] = {0};
360 if(NULL == getcwd(pathBuf, sizeof(pathBuf) - 1)) return 1;
361 CrString path = pathBuf;
362 #else
363 CrString path = fs::current_path().native();
364 #endif
365
366 bool boolRet = SCRSDK::Init();
367 if(!boolRet) GotoError("", 0);
368
369 // enumeration
370 {
371 uint32_t count = 0;
372 uint32_t index = 1;
373
374 err = SCRSDK::EnumCameraObjects(&enumCameraObjectInfo, 3/*timeInSec*/);
375 if(err || !enumCameraObjectInfo) GotoError("no camera", err);
376
377 count = enumCameraObjectInfo->GetCount();
378 if(count >= 2) {
379 for (uint32_t i = 0; i < count; ++i) {
380 auto* info = enumCameraObjectInfo->GetCameraObjectInfo(i);
381 CrCout << '[' << i + 1 << "] " << _getModelId(info) << "\n";
382 }
383
384 std::string inputLine;
385 std::cout << "select camera:"; std::getline(std::cin, inputLine);
386 try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
387 if(index < 1 || index > count) GotoError("", 0);
388 }
389 objInfo = (SCRSDK::ICrCameraObjectInfo*)enumCameraObjectInfo->GetCameraObjectInfo(index - 1);
390 m_modelId = _getModelId(objInfo);
391 }
392
393 // connect
394 {
395 std::string fingerprint = "";
396 std::string userId = "";
397 std::string userPassword = "";
398 std::promise<void> eventPromise;
399 std::future<void> eventFuture = eventPromise.get_future();
400
401 if (objInfo->GetSSHsupport() == SCRSDK::CrSSHsupport_ON) {
402 err = _getIdPassword(objInfo, fingerprint, userId, userPassword); if(err) goto Error;
403 }
404
405 setEventPromise(&eventPromise);
406 err = SCRSDK::Connect(objInfo, &deviceCallback, &m_device_handle,
407 SCRSDK::CrSdkControlMode_Remote,
408 SCRSDK::CrReconnecting_ON,
409 userId.c_str(), userPassword.c_str(), fingerprint.c_str(), (uint32_t)fingerprint.size());
410 if(err) GotoError("", err);
411
412 // std::future_status status = eventFuture.wait_for(std::chrono::milliseconds(3000));
413 // if(status != std::future_status::ready) GotoError("timeout",0);
414 try{
415 eventFuture.get();
416 } catch(const std::exception&) GotoError("", 0);
417 }
418
419 // set work directory
420 {
421 CrCout << "path=" << path.data() << "\n";
422 err = SCRSDK::SetSaveInfo(m_device_handle, const_cast<CrChar*>(path.data()), const_cast<CrChar*>(CRSTR("DSC")), -1/*startNo*/);
423 if(err) GotoError("", err);
424 }
425
426 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
427
428 std::cout << "usage:\n";
429 std::cout << " setdp <DP name> <param> [1-blocking,0-no blocking]\n";
430 std::cout << " getdp <DP name>\n";
431 std::cout << " infodp <DP name>\n";
432 std::cout << " listdp\n";
433 std::cout << " send <command name> <param>\n";
434 std::cout << " setcc <control code> <param>\n";
435 std::cout << " infocc <control code>\n";
436 std::cout << " listcc\n";
437 std::cout << "To exit, please enter 'q'.\n";
438
439 while(1) {
440 std::string inputLine;
441 std::getline(std::cin, inputLine);
442 std::vector<std::string> args = _split(inputLine, ' ');
443
444 if(args.size() == 0) {
445
446 } else if(args[0] == "q" || args[0]== "Q") {
447 break;
448 } else if(args[0] == "send" && args.size() >= 3) {
449 int64_t data = 0;
450 int32_t code = CrCommandIdCode(args[1]);
451 if(code < 0) continue;
452 try{ data = _stoll(args[2]); } catch(const std::exception&) {continue;}
453
454 err = SCRSDK::SendCommand(m_device_handle, code, (SCRSDK::CrCommandParam)data);
455 if(err) GotoError("", err);
456
457 } else if(args[0] == "setdp" && args.size() >= 3) {
458 int64_t data = 0;
459 bool blocking = true;
460 int32_t code = CrDevicePropertyCode(args[1]);
461 if(code < 0) continue;
462
463 try{ data = _stoll(args[2]); } catch(const std::exception&) {continue;}
464 if(args.size() >= 4)
465 try{ blocking = _stoll(args[3]); } catch(const std::exception&) {continue;}
466
467 err = _setDeviceProperty(m_device_handle, code, data, blocking);
468 if(err) continue;
469
470 } else if((args[0] == "getdp" || args[0] == "infodp") && args.size() >= 2) {
471 // device property get/info
472 int32_t code = CrDevicePropertyCode(args[1]);
473 if(code < 0) continue;
474
475 SCRSDK::CrDeviceProperty devProp;
476 err = _getDeviceProperty(m_device_handle, code, &devProp);
477 if(err) continue;
478 SCRSDK::CrDataType dataType = devProp.GetValueType();
479
480 if(args[0] == "getdp") {
481 if(dataType == SCRSDK::CrDataType_STR) {
482 CrCout << _getCurrentStr(&devProp) << "\n";
483 } else {
484 printf("0x%" PRIx64 "(%" PRId64 ")\n", devProp.GetCurrentValue(), devProp.GetCurrentValue()); // macro for %lld
485 }
486 } else if(args[0] == "infodp") {
487 printf(" get enable=%d\n", devProp.IsGetEnableCurrentValue());
488 printf(" set enable=%d\n", devProp.IsSetEnableCurrentValue());
489 printf(" variable =%d\n", devProp.GetPropertyVariableFlag());
490 printf(" enable =%d\n", devProp.GetPropertyEnableFlag());
491 printf(" valueType =0x%x\n", dataType);
492 if(dataType == SCRSDK::CrDataType_STR) {
493 CrCout << " current =\"" << _getCurrentStr(&devProp) << "\"\n";
494 } else {
495 printf(" current =0x%" PRIx64 "(%" PRId64 ")\n", devProp.GetCurrentValue(), devProp.GetCurrentValue());
496
497 std::vector<int64_t> possible = _getPossible(devProp.GetValueType(), devProp.GetValues(), devProp.GetValueSize());
498 printf(" possible =");
499 for(int i = 0; i < possible.size(); i++) {
500 printf("0x%" PRIx64 "(%" PRId64 "),", possible[i], possible[i]);
501 }
502 printf("\n");
503 }
504 }
505 } else if(args[0] == "listdp") {
506 std::int32_t nprop = 0;
507 SCRSDK::CrDeviceProperty* prop_list = nullptr;
508 SCRSDK::CrError err = SCRSDK::GetDeviceProperties(m_device_handle, &prop_list, &nprop);
509 if(err) GotoError("", err);
510
511 for(int i = 0; i < nprop; i++) {
512 printf("%s\n", CrDevicePropertyString((SCRSDK::CrDevicePropertyCode)prop_list[i].GetCode()).c_str());
513 }
514 SCRSDK::ReleaseDeviceProperties(m_device_handle, prop_list);
515
516 } else if(args[0] == "setcc" && args.size() >= 3) {
517 int64_t data = 0;
518 SCRSDK::CrControlCode code = CrControlCode(args[1]);
519 if(code < 0) continue;
520
521 SCRSDK::CrControlCodeInfo* info = NULL;
522 err = SCRSDK::GetSelectControlCode(m_device_handle, code, &info);
523 if(err) GotoError("", err);
524
525 SCRSDK::CrDataType dataType = info->GetValueType();
526 SCRSDK::ReleaseControlCodes(m_device_handle, info);
527
528 if(dataType != SCRSDK::CrDataType_STR) {
529 try{ data = _stoll(args[2]); } catch(const std::exception&) {continue;}
530 err = SCRSDK::ExecuteControlCodeValue(m_device_handle, code, data);
531 if(err) GotoError("", err);
532 } else {
533 CrString str = Utf8ToCr(args[2]);
534 size_t len = str.length() + 1;
535 if (len == 1) GotoError("Character size error", 0);
536 if (len > (size_t)info->GetValueSize()) GotoError("Character size error", 0);
537 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
538 std::u16string utf16Str = converter.from_bytes(args[2]);
539 err = SCRSDK::ExecuteControlCodeString(m_device_handle, code, (CrInt16u)utf16Str.length() + 1, (CrInt16u*)utf16Str.c_str());
540 if(err) GotoError("", err);
541 }
542
543 } else if(args[0] == "infocc" && args.size() >= 2) {
544 int64_t data = 0;
545 SCRSDK::CrControlCode code = CrControlCode(args[1]);
546 if(code < 0) continue;
547
548 SCRSDK::CrControlCodeInfo* info = NULL;
549 err = SCRSDK::GetSelectControlCode(m_device_handle, code, &info);
550 if(err) GotoError("", err);
551
552 SCRSDK::CrDataType dataType = info->GetValueType();
553 printf(" code =0x%x\n", code);
554 printf(" valueType =0x%x\n", dataType);
555 if(dataType != SCRSDK::CrDataType_STR) {
556 std::vector<int64_t> possible = _getPossible(dataType, info->GetValues(), info->GetValueSize());
557 printf(" possible =");
558 for(int i = 0; i < possible.size(); i++) {
559 printf("0x%" PRIx64 "(%" PRId64 "),", possible[i], possible[i]);
560 }
561 printf("\n");
562 }
563 SCRSDK::ReleaseControlCodes(m_device_handle, info);
564
565 } else if(args[0] == "listcc") {
566 SCRSDK::CrControlCodeInfo* infos = NULL;
567 CrInt32u numOfInfos = 0;
568 err = GetSupportedControlCodes(m_device_handle, &infos, &numOfInfos);
569 if(err) GotoError("", err);
570
571 for(int i = 0; i < (int)numOfInfos; i++) {
572 printf("%s\n", CrControlCodeString(infos[i].GetCode()).c_str());
573 }
574 SCRSDK::ReleaseControlCodes(m_device_handle, infos);
575
576 } else {
577 std::cout << "unknown command\n";
578 }
579 }
580
581 result = 0;
582Error:
583 if(enumCameraObjectInfo) enumCameraObjectInfo->Release();
584
585 if(m_connected) {
586 std::promise<void> eventPromise;
587 std::future<void> eventFuture = eventPromise.get_future();
588 setEventPromise(&eventPromise);
589 SCRSDK::Disconnect(m_device_handle);
590 int msec = 3000; // 3 seconds
591 if (m_lvProtocolChanged) msec *= 10; // x10
592 // If CrLiveViewProtocol_Alt is selected, the disconnection process may take some time.
593 eventFuture.wait_for(std::chrono::milliseconds(msec));
594 }
595 if (m_device_handle) SCRSDK::ReleaseDevice(m_device_handle);
596 SCRSDK::Release();
597
598 return result;
599}