sample code - “FTPServerSetting”

usage:
   set <id> <display> <host> <port> <user> [passExist] [pass] [passive] [dest] [secure] [hierarchy] [overwrite] [rootcert]
   get <id>
   result <slot>
To exit, please enter 'q'.
sample:
   set 1 FTP1 192.168.11.16 21 test
   set 1 FTP1 192.168.11.16 21 test 1 test 2 "" 1 1 1 2

This sample code is included in SimpleCli.

  1// "FTP server setting" sample
  2#include <chrono>
  3#include <codecvt>
  4#include <cstdint>
  5#include <cstdlib>
  6#include <fstream>
  7#include <future>
  8#include <iostream>
  9#include <mutex>
 10#include <stdexcept>
 11#include <string>
 12#include <thread>
 13#include <vector>
 14
 15#if !defined(__APPLE__)
 16  #if defined(USE_EXPERIMENTAL_FS) // for jetson
 17    #include <experimental/filesystem>
 18    namespace fs = std::experimental::filesystem;
 19  #else
 20    #include <filesystem>
 21    namespace fs = std::filesystem;
 22  #endif
 23#endif
 24
 25#if defined(_WIN32) || defined(_WIN64)
 26  #include <fcntl.h>
 27  #include <io.h>
 28#else
 29  #include <unistd.h>
 30#endif
 31
 32// macro for multibyte character
 33#if defined(_WIN32) || defined(_WIN64)
 34  using CrString = std::wstring;
 35  #define CRSTR(s) L ## s
 36  #define CrCout std::wcout
 37  #define CrCin std::wcin
 38  #define CrPrintf std::wprintf
 39  #define DELIMITER CRSTR("\\")
 40  #define CrToUtf8(a) wstring_convert.to_bytes(a)
 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  using CrString = std::string;
 45  #define CRSTR(s) s
 46  #define CrCout std::cout
 47  #define CrCin std::cin
 48  #define CrPrintf std::printf
 49  #define DELIMITER CRSTR("/")
 50  #define CrToUtf8(a) (a)
 51  #define Utf8ToCr(a) (a)
 52#endif
 53
 54#include "CrDeviceProperty.h"
 55#include "CameraRemote_SDK.h"
 56#include "IDeviceCallback.h"
 57#include "CrDebugString.h"   // use CrDebugString.cpp
 58
 59#define PrintError(msg, err) { fprintf(stderr, "Error in %s(%d):" msg ",%s\n", __FUNCTION__, __LINE__, (err ? CrErrorString(err).c_str():"")); }
 60#define GotoError(msg, err) { PrintError(msg, err); goto Error; }
 61
 62bool  m_connected = false;
 63CrString m_modelId;
 64
 65std::mutex m_eventPromiseMutex;
 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
 73class DeviceCallback : public SCRSDK::IDeviceCallback
 74{
 75public:
 76    DeviceCallback() {};
 77    ~DeviceCallback() {};
 78
 79    void OnConnected(SCRSDK::DeviceConnectionVersioin version)
 80    {
 81        CrCout << "Connected to " << m_modelId << "\n";
 82        m_connected = true;
 83        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 84        if(m_eventPromise) {
 85            m_eventPromise->set_value();
 86            m_eventPromise = nullptr;
 87        }
 88    }
 89
 90    void OnError(CrInt32u error)
 91    {
 92        printf("Connection error:%s\n", CrErrorString(error).c_str());
 93        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 94        if(m_eventPromise) {
 95            m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
 96            m_eventPromise = nullptr;
 97        }
 98    }
 99
100    void OnDisconnected(CrInt32u error)
101    {
102        CrCout << "Disconnected from " << m_modelId << "\n";
103        m_connected = false;
104        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
105        if(m_eventPromise) {
106            m_eventPromise->set_value();
107            m_eventPromise = nullptr;
108        }
109    }
110
111    void OnCompleteDownload(CrChar* filename, CrInt32u type)
112    {
113        CrCout << "OnCompleteDownload:" << filename << "\n";
114    }
115
116    void OnNotifyContentsTransfer(CrInt32u notify, SCRSDK::CrContentHandle contentHandle, CrChar* filename)
117    {
118        std::cout << "OnNotifyContentsTransfer.\n";
119    }
120
121    void OnWarning(CrInt32u warning)
122    {
123        if (warning == SCRSDK::CrWarning_Connect_Reconnecting) {
124            CrCout << "Reconnecting to " << m_modelId << "\n";
125            return;
126        }
127        std::cout << "OnWarning:" << CrErrorString(warning) << "\n";
128        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
129        switch(warning) {
130        case SCRSDK::CrWarning_RequestFTPServerSettingList_Success:
131        case SCRSDK::CrWarning_SetFTPServerSetting_Result_OK:
132            if(m_eventPromise) {
133                m_eventPromise->set_value();
134                m_eventPromise = nullptr;
135            }
136            break;
137        case SCRSDK::CrWarning_RequestFTPServerSettingList_DeviceBusy:
138        case SCRSDK::CrWarning_RequestFTPServerSettingList_Error:
139            if(m_eventPromise) {
140                m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
141                m_eventPromise = nullptr;
142            }
143            break;
144    //  case SCRSDK::CrWarning_FTP_Display_Name_List_Changed:
145        }
146    }
147
148
149    void OnWarningExt(CrInt32u warning, CrInt32 param1, CrInt32 param2, CrInt32 param3)
150    {
151        std::cout << "OnWarningExt:" << CrWarningExtString(warning, param1, param2, param3).c_str() << "\n";
152    }
153
154    void OnLvPropertyChanged() {}
155    void OnLvPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
156    void OnPropertyChanged() {}
157    void OnPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
158
159    void OnNotifyFTPTransferResult(CrInt32u notify, CrInt32u numOfSuccess, CrInt32u numOfFail)
160    {
161        printf("OnNotifyFTPTransferResult(%s):success=%d,fail=%d\n", CrErrorString(notify).c_str(), numOfSuccess, numOfFail);
162        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
163        switch(notify) {
164        case SCRSDK::CrNotify_FTPTransferResult_Success:
165            if(m_eventPromise) {
166                m_eventPromise->set_value();
167                m_eventPromise = nullptr;
168            }
169            break;
170        case SCRSDK::CrNotify_FTPTransferResult_Failure:
171            if(m_eventPromise) {
172                m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
173                m_eventPromise = nullptr;
174            }
175            break;
176        }
177    }
178};
179
180CrString _getModelId(const SCRSDK::ICrCameraObjectInfo* objInfo)
181{
182    CrString id;
183    if (CrString(objInfo->GetConnectionTypeName()) == CRSTR("IP")) {
184        id = CrString(objInfo->GetMACAddressChar());
185    } else {
186        id = CrString((CrChar*)objInfo->GetId());
187    }
188    return CrString(objInfo->GetModel()).append(CRSTR(" (")).append(id).append(CRSTR(")"));
189}
190
191SCRSDK::CrError _getIdPassword(SCRSDK::ICrCameraObjectInfo* objInfo, std::string& fingerprint, std::string& userId, std::string& userPassword)
192{
193    char fpBuff[128] = {0};
194    CrInt32u fpLen = 0;
195    SCRSDK::CrError err = SCRSDK::GetFingerprint(objInfo, fpBuff, &fpLen);
196    if(err) GotoError("", err);
197    fingerprint = std::string(fpBuff, fpLen);
198
199    std::cout << "fingerprint: " << fingerprint.c_str() << "\n";
200    std::cout << "id:";       std::getline(std::cin, userId);
201    std::cout << "password:"; std::getline(std::cin, userPassword);
202    return 0;
203Error:
204    return err;
205}
206
207int64_t _stoll(CrString inputLine)
208{
209    int64_t data = 0;
210    if(inputLine.empty()) throw std::runtime_error("error");
211    try {
212        if (inputLine.compare(0, 2, CRSTR("0x")) == 0 || inputLine.compare(0, 2, CRSTR("0X")) == 0) {
213            data = std::stoull(inputLine.substr(2), nullptr, 16);
214        } else {
215            data = std::stoll(inputLine, nullptr, 10);
216        }
217    } catch(const std::exception& ex) {
218        throw ex;
219    }
220    return data;
221}
222
223void _printFTPServerSetting(SCRSDK::CrFTPServerSetting* setting)
224{
225    #define _printUtf8(msg, dp) { \
226        const char* _dp = dp; \
227        std::cout << msg; \
228        if(_dp) CrCout << Utf8ToCr(_dp); \
229        std::cout << "\n"; \
230    }
231
232    printf("serverId:%d\n",                 setting->serverId);
233    printf("serviceType:%d\n",              setting->serviceType);
234    _printUtf8("displayName:",              setting->GetDisplayName());
235    _printUtf8("hostName:",                 setting->GetHostName());
236    printf("portNumber:%d\n",               setting->portNumber);
237    _printUtf8("userName:",                 setting->GetUserName_());
238    printf("passwordExists:%d\n",           setting->passwordExists);
239    _printUtf8("password:",                 setting->GetPassword());
240    printf("passiveMode:%d\n",              setting->passiveMode);
241    _printUtf8("destinationDir:",           setting->GetDestinationDir());
242    printf("secureProtocol:%d\n",           setting->secureProtocol);
243    printf("directoryHierarchyType:%d\n",   setting->directoryHierarchyType);
244    printf("overwriteType:%d\n",            setting->overwriteType);
245    printf("rootCertificateErrorSetting:%d\n", setting->rootCertificateErrorSetting);
246    return;
247}
248
249SCRSDK::CrError _setFTPServerSetting(int64_t device_handle, std::vector<CrString>& args)
250{
251    int result = SCRSDK::CrError_Generic_Unknown;
252    SCRSDK::CrError err = SCRSDK::CrError_None;
253
254    CrInt16u serverId = 0;
255    std::string displayName;
256    std::string hostName;
257    CrInt16u portNumber = 0;
258    std::string userName;
259    SCRSDK::CrFTPServerPasswordExists               passwordExists = SCRSDK::CrFTPServerPassword_NotUse;
260    std::string                                     password = "";
261    SCRSDK::CrFTPServerPassiveMode                  passiveMode = SCRSDK::CrFTPServerPassiveMode_On;
262    std::string                                     destinationDir = "";
263    SCRSDK::CrFTPServerUsingSecureProtocol          secureProtocol = SCRSDK::CrFTPServerUsingSecureProtocol_Off;
264    SCRSDK::CrFTPServerDirectoryHierarchyType       directoryHierarchyType = SCRSDK::CrFTPServerDirectoryHierarchyType_Standard;
265    SCRSDK::CrFTPServerSameNameFileOverwriteType    overwriteType = SCRSDK::CrFTPServerSameNameFileOverwriteType_Overwrite;
266    SCRSDK::CrFTPServerRootCertificateErrorSetting  rootCertificateErrorSetting = SCRSDK::CrFTPServerRootCertificateErrorSetting_NotConnect;
267
268    SCRSDK::CrFTPServerSetting* setSetting = nullptr;
269    std::promise<void> eventPromise;
270    std::future<void> eventFuture = eventPromise.get_future();
271
272    try {
273        if (args.size() < 6) GotoError("", 0);
274        serverId = (CrInt16u)_stoll(args[1]);
275        displayName = CrToUtf8(args[2]);
276        hostName = CrToUtf8(args[3]);
277        portNumber = (CrInt16u)_stoll(args[4]);
278        userName = CrToUtf8(args[5]);
279        if (args.size() >= 7) passwordExists                = (SCRSDK::CrFTPServerPasswordExists)_stoll(args[6]);
280        if (args.size() >= 8) password                      = CrToUtf8(args[7]);
281        if (args.size() >= 9) passiveMode                   = (SCRSDK::CrFTPServerPassiveMode)_stoll(args[8]);
282        if (args.size() >= 10) destinationDir               = CrToUtf8(args[9]);
283        if (args.size() >= 11) secureProtocol               = (SCRSDK::CrFTPServerUsingSecureProtocol)_stoll(args[10]);
284        if (args.size() >= 12) directoryHierarchyType       = (SCRSDK::CrFTPServerDirectoryHierarchyType)_stoll(args[11]);
285        if (args.size() >= 13) overwriteType                = (SCRSDK::CrFTPServerSameNameFileOverwriteType)_stoll(args[12]);
286        if (args.size() >= 14) rootCertificateErrorSetting  = (SCRSDK::CrFTPServerRootCertificateErrorSetting)_stoll(args[13]);
287    } catch(const std::exception&) { GotoError("", 0); }
288
289    setSetting = new SCRSDK::CrFTPServerSetting(
290                                serverId,
291                                SCRSDK::CrFTPServerServiceType_FTP,
292                                displayName.c_str(),
293                                hostName.c_str(),
294                                portNumber,
295                                userName.c_str(),
296                                passwordExists,
297                                password.c_str(),
298                                passiveMode,
299                                destinationDir.c_str(),
300                                secureProtocol,
301                                directoryHierarchyType,
302                                overwriteType,
303                                rootCertificateErrorSetting);
304    _printFTPServerSetting(setSetting);
305
306    setEventPromise(&eventPromise);
307
308    err = SCRSDK::SetFTPServerSetting(device_handle, setSetting);
309    if(err) GotoError("", err);
310
311    try{
312        eventFuture.get();
313    } catch(const std::exception&) GotoError("", 0);
314
315    std::cout << "OK\n";
316    result = 0;
317Error:
318    setEventPromise(nullptr);
319    if(setSetting) delete setSetting;
320    return result;
321}
322
323SCRSDK::CrError _getFTPServerSetting(int64_t device_handle, uint32_t index)
324{
325    int result = SCRSDK::CrError_Generic_Unknown;
326    SCRSDK::CrError err = SCRSDK::CrError_None;
327    std::promise<void> eventPromise;
328    std::future<void> eventFuture = eventPromise.get_future();
329
330    // request FTPServerSettingList
331    setEventPromise(&eventPromise);
332
333    err = SCRSDK::RequestFTPServerSettingList(device_handle);
334    if(err) GotoError("", err);
335
336    try{
337        eventFuture.get();
338    } catch(const std::exception&) GotoError("", 0);
339
340    // Get FTPServerSettingList
341    {
342        SCRSDK::CrFTPServerSetting* ftpServerSettingList = nullptr;
343        CrInt32u ftpServerSettingListSize = 0;
344
345        err = SCRSDK::GetFTPServerSettingList(device_handle, &ftpServerSettingList, &ftpServerSettingListSize);
346        if(err || ftpServerSettingListSize == 0) GotoError("", err);
347
348        printf("serverId=1~%d\n", (int)ftpServerSettingListSize);
349        if (index > 0 && index <= ftpServerSettingListSize) {
350            _printFTPServerSetting(ftpServerSettingList + (index-1));
351        }
352        SCRSDK::ReleaseFTPServerSettingList(device_handle, ftpServerSettingList);
353    }
354
355    result = 0;
356Error:
357    setEventPromise(nullptr);
358    return result;
359}
360
361
362std::vector<CrString> CrSplit(const CrString &inputLine)
363{
364    std::vector<CrString> strArray;
365    CrString tmp;
366    bool inQuotes = false;
367
368    for (size_t i = 0; i < inputLine.size(); ++i) {
369        CrChar c = inputLine[i];
370
371        if (c == CRSTR('"')) {
372            inQuotes = !inQuotes;
373        } else if (c == CRSTR(' ') && !inQuotes) {
374            strArray.push_back(tmp);
375            tmp.clear();
376        } else {
377            tmp += c;
378        }
379    }
380    strArray.push_back(tmp);
381    return strArray;
382}
383
384int main(void)
385{
386    int result = -1;
387    SCRSDK::CrError err = SCRSDK::CrError_None;
388    int64_t  m_device_handle = 0;
389    SCRSDK::ICrEnumCameraObjectInfo* enumCameraObjectInfo = nullptr;
390    SCRSDK::ICrCameraObjectInfo* objInfo = nullptr;
391    DeviceCallback deviceCallback;
392
393  #if defined(__APPLE__)
394    #define MAC_MAX_PATH 255
395    char pathBuf[MAC_MAX_PATH] = {0};
396    if(NULL == getcwd(pathBuf, sizeof(pathBuf) - 1)) return 1;
397    CrString path = pathBuf;
398  #else
399    CrString path = fs::current_path().native();
400  #endif
401
402    bool boolRet = SCRSDK::Init();
403    if(!boolRet) GotoError("", 0);
404
405    // enumeration
406    {
407        uint32_t count = 0;
408        uint32_t index = 1;
409
410        err = SCRSDK::EnumCameraObjects(&enumCameraObjectInfo, 3/*timeInSec*/);
411        if(err || !enumCameraObjectInfo) GotoError("no camera", err);
412
413        count = enumCameraObjectInfo->GetCount();
414        if(count >= 2) {
415            for (uint32_t i = 0; i < count; ++i) {
416                auto* info = enumCameraObjectInfo->GetCameraObjectInfo(i);
417                CrCout << '[' << i + 1 << "] " << _getModelId(info) << "\n";
418            }
419
420            std::string inputLine;
421            std::cout << "select camera:"; std::getline(std::cin, inputLine);
422            try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
423            if(index < 1 || index > count) GotoError("", 0);
424        }
425        objInfo = (SCRSDK::ICrCameraObjectInfo*)enumCameraObjectInfo->GetCameraObjectInfo(index - 1);
426        m_modelId = _getModelId(objInfo);
427    }
428
429    // connect
430    {
431        std::string  fingerprint = "";
432        std::string  userId = "";
433        std::string  userPassword = "";
434        std::promise<void> eventPromise;
435        std::future<void> eventFuture = eventPromise.get_future();
436
437        if (objInfo->GetSSHsupport() == SCRSDK::CrSSHsupport_ON) {
438            err = _getIdPassword(objInfo, fingerprint, userId, userPassword); if(err) goto Error;
439        }
440
441        setEventPromise(&eventPromise);
442        err = SCRSDK::Connect(objInfo, &deviceCallback, &m_device_handle,
443            SCRSDK::CrSdkControlMode_Remote,
444            SCRSDK::CrReconnecting_ON,
445            userId.c_str(), userPassword.c_str(), fingerprint.c_str(), (uint32_t)fingerprint.size());
446        if(err) GotoError("", err);
447
448    //  std::future_status status = eventFuture.wait_for(std::chrono::milliseconds(3000));
449    //  if(status != std::future_status::ready) GotoError("timeout",0);
450        try{
451            eventFuture.get();
452        } catch(const std::exception&) GotoError("", 0);
453    }
454
455    // set work directory
456    {
457        CrCout << "path=" << path.data() << "\n";
458        err = SCRSDK::SetSaveInfo(m_device_handle, const_cast<CrChar*>(path.data()), const_cast<CrChar*>(CRSTR("DSC")), -1/*startNo*/);
459        if(err) GotoError("", err);
460    }
461
462    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
463
464  #if defined(_WIN32) || defined(_WIN64)
465    _setmode(_fileno(stdin), _O_U16TEXT);
466  #endif
467
468    std::cout << "usage:\n";
469    std::cout << "   set <id> <display> <host> <port> <user> [passExist] [pass] [passive] [dest] [secure] [hierarchy] [overwrite] [rootcert]\n";
470    std::cout << "   get <id>\n";
471    std::cout << "   result <slot>\n";
472    std::cout << "To exit, please enter 'q'.\n";
473
474    while(1) {
475        CrString inputLine;
476        std::getline(CrCin, inputLine);
477        std::vector<CrString> args = CrSplit(inputLine);
478
479        if((args[0] == CRSTR("set") || args[0] == CRSTR("s")) && args.size() >= 6) {
480            err = _setFTPServerSetting(m_device_handle, args);
481            if(err) goto Error;
482
483        } else if((args[0] == CRSTR("get") || args[0] == CRSTR("g")) && args.size() >= 2) {
484            uint32_t id;
485            try { id = stoi(args[1]); } catch(const std::exception&) { GotoError("", 0); }
486            err = _getFTPServerSetting(m_device_handle, id);
487            if(err) goto Error;
488
489        } else if(args[0] == CRSTR("result") && args.size() >= 2) {
490            uint32_t slot;
491            try { slot = stoi(args[1]); } catch(const std::exception&) { GotoError("", 0); }
492            err = SCRSDK::RequestFTPTransferResult(m_device_handle, (SCRSDK::CrSlotNumber)slot);
493            if(err) goto Error;
494
495        } else if(args[0] == CRSTR("q") || args[0] == CRSTR("Q")) {
496            break;
497        } else {
498            std::cout << "unknown command\n";
499        }
500    }
501
502    result = 0;
503Error:
504    if(enumCameraObjectInfo) enumCameraObjectInfo->Release();
505
506    if(m_connected) {
507        std::promise<void> eventPromise;
508        std::future<void> eventFuture = eventPromise.get_future();
509        setEventPromise(&eventPromise);
510        SCRSDK::Disconnect(m_device_handle);
511        eventFuture.wait_for(std::chrono::milliseconds(3000));
512    }
513    if(m_device_handle) SCRSDK::ReleaseDevice(m_device_handle);
514    SCRSDK::Release();
515
516    return result;
517}