Commit e2e8adf6 authored by Martin Cífka's avatar Martin Cífka
Browse files

added notifications handling; enums (msg_id, iso, speed etc...) moved to codes.h

parent d09886e9
Loading
Loading
Loading
Loading
Loading

sdk/src/codes.h

0 → 100644
+180 −0
Original line number Diff line number Diff line
#ifndef CODES_H
#define CODES_H

#include <string>

class Codes
{
public:
    enum class MsgId
    {
        GetToken = 257,
        DropToken = 258,
        Shoot = 4864,
        SetSpeed = 5171,
        SetISO = 5172,
        
        ImgCaptured = 8193,
                
        GetCameraState = 4362,
        SetCameraMode = 4611 //button press
    };
    
    enum class ParamCameraState
    {
        Idle = 0,
        Standby = 1,
        Storage = 2,
        Capturing = 3,
        CapturingMicro = 4,
        CapturingDelayed = 5,
        Photoing = 6,
        PhotoingDelayed = 7,
        PhotoingInterval = 12,
        CapturingSlow = 13,
        CapturingContinuous = 14,
        CapturingSurroundexp = 15
    };
    
    enum class ParamWhitebalance
    {
        Auto = 0,
        Outdoor = 1, 
        Shadow = 2,
        Cloudy = 3,
        Night = 4
    };
    
    enum class Rval
    {
        CommandOk = 0,
        NotificationOk = 128,
        ErrorBusy = -21,
        ErrorInvalidFilePath = -26,
        ErrorInvalidOperation = -14,
        ErrorInvalidToken = -4,
        ErrorLowBattery = -58,
        ErrorNoFirmware = -57,
        ErrorNoSdcard = -50,
        ErrorSdcard = -59,
        ErrorScardFull = -17,
        ErrorSdcardSlowly = -61,
        ErrorWrongMode = -56,
        StartSessionDenied = -3        
    };
    
    enum class ISO
    {
        Auto = 0,
        I50 = 50,
        I100 = 100,
        I200 = 200,
        I400 = 400,
        I800 = 800,
        I1600 = 1600
    };
    
    enum class Speed
    {
        Auto = 0,
        
        S1_6400 = 32768 + 6400,
        S1_3200 = 32768 + 3200,
        S1_2000 = 32768 + 2000,
        S1_1000 = 32768 + 1000,
        S1_500 = 32768 + 500,
        S1_240 = 32768 + 240,
        S1_120 = 32768 + 120,
        S1_60 = 32768 + 60,
        S1_30 = 32768 + 30,
        S1_15 = 32768 + 15,
        S1_8 = 32768 + 8,
        S1_4 = 32768 + 4,
        
        S1 = 1,
        S2 = 2,
        S4 = 4,
        S8 = 8,
        S12 = 12,
        S16 = 16,
        S20 = 20,
        S24 = 24,
        S28 = 28,
        S32 = 32
    };
    
    enum class ParamBattery
    {
        Percent5 = 0,
        Percent25 = 1,
        Percent50 = 2,
        Percent75 = 3,
        Percent100 = 4,    
        ChargeFull = 68  
    };
    
    enum class ParamMode
    {
        Video = 0,
        Photo = 1
    };
    
    enum class ParamSdcardFull
    {
        No = 0,
        Almost = 1,
        Yes = 2,
        Unknown = 3
    };
    
    enum class ParamSdcardMounted
    {
        No = 0,
        Yes = 1
    };
    
    enum class ParamSdcardNeedFormat
    {
        No = 0,
        Yes = 1
    };
    
    
    
    
    static std::string stateToString(int state)
    {
        switch (state)
        {
            case (int)ParamCameraState::Idle:
                return "idle";
            case (int)ParamCameraState::Standby:
                return "standby";
            case (int)ParamCameraState::Storage:
                return "storage";
            case (int)ParamCameraState::Capturing:
                return "capturing";
            case (int)ParamCameraState::CapturingMicro:
                return "capturing micro";
            case (int)ParamCameraState::CapturingDelayed:
                return "capturing delayed";
            case (int)ParamCameraState::Photoing:
                return "photoing";
            case (int)ParamCameraState::PhotoingDelayed:
                return "photoing delayed";
            case (int)ParamCameraState::PhotoingInterval:
                return "photoing interval";
            case (int)ParamCameraState::CapturingSlow:
                return "capturing slow";
            case (int)ParamCameraState::CapturingContinuous:
                return "capturing continuous";
            case (int)ParamCameraState::CapturingSurroundexp:
                return "capturing surroundexp";
            default:
                return "invalid";
        }
    }
};


#endif /* CODES_H */
 No newline at end of file
+73 −37
Original line number Diff line number Diff line
#include <cerrno>
#include <climits>

#include <iostream>

#include "commander.h"
#include <iostream>

using namespace std;

Commander::Commander() :
    _token(0), _sock(TcpSocket()), _reader(CustomReader(&_sock)) {};
    
string Commander::generateJSON(MSG msg)
string Commander::generateJSON(Codes::MsgId msg)
{
    DynamicJsonDocument json(JSON_OBJECT_SIZE(2));
    json["msg_id"] = (int)msg;
@@ -22,10 +21,10 @@ string Commander::generateJSON(MSG msg)
    return str;
}

string Commander::generateJSON(MSG msg, int param)
string Commander::generateJSON(Codes::MsgId msg, int param)
{
    DynamicJsonDocument json(JSON_OBJECT_SIZE(3));
    json["msg_id"] = (int)MSG::setSpeed;
    json["msg_id"] = (int)msg;
    json["param"] = (int)param;
    json["token"] = _token;
    
@@ -35,7 +34,44 @@ string Commander::generateJSON(MSG msg, int param)
    return str;
}

bool Commander::getJSON(DynamicJsonDocument& json, MSG expected_msg_id, int expected_rval)
void Commander::handleMsgId(DynamicJsonDocument& json)
{
    cout << "NOTIFICATION: ";
            
    //TODO: add more ids
    switch ((int)json["msg_id"])
    {
        case (int)Codes::MsgId::GetCameraState:
        {
            cout << "Camera state: ";
            string key = "param";
            if (!json.containsKey(key) || !json[key].is<int>())
                cout << "invalid" << endl;
            else
                cout << Codes::stateToString(json[key]) << endl;
            
            break;
        }
        
        case (int)Codes::MsgId::SetCameraMode:
        {
            cout << "Camera mode set to: ";
            string key = "param";
            if (!json.containsKey(key) || !json[key].is<int>() || json[key] < 0 || json[key] > 1)
                cout << "invalid" << endl;
            else
                cout << (json[key] == (int)Codes::ParamMode::Video ? "video" : "photo" ) << endl;
            break;
        }
        
        default:
            cout << _reader.history << endl;
            break;
    }
}


bool Commander::getJSON(DynamicJsonDocument& json, Codes::MsgId expected_msg_id, Codes::Rval expected_rval)
{
    // Get response
    for (int i = 0; i < 3; ++i) // make 3 attempts to receive json
@@ -66,24 +102,27 @@ bool Commander::getJSON(DynamicJsonDocument& json, MSG expected_msg_id, int expe
            case DeserializationError::NotSupported:    
            case DeserializationError::IncompleteInput: // this won't happen, as recv (deserializeJson) would time out
                cerr << "Error: couldn't parse JSON (" << err.c_str() << "): " << _reader.history << endl;
                cerr << "Restarting socket...";
                _sock.close();
                connect();
                //TODO: try again
                break;
        }


        string key = "msg_id";
        if (!json.containsKey(key) || !json[key].is<int>() || json[key] != (int)expected_msg_id)
        if (!json.containsKey(key) || !json[key].is<int>())
        {
            //TODO: Handle unexpected msg_id
            //handleMsgId(json);
            cerr << "Error: unexpected msg_id: " << _reader.history << endl;
            cerr << "Unexpected JSON response: " << _reader.history << endl;
            continue;
        }
        else if (json[key] != (int)expected_msg_id)
        {
            handleMsgId(json);
            continue;
        }

        key = "rval";
        if (!json.containsKey(key) || !json[key].is<int>() || json[key] != expected_rval)
        if (!json.containsKey(key) || !json[key].is<int>() || json[key] != (int)expected_rval)
        {
            //TODO: Handle invalid rval
            //handleRval(json);
@@ -114,19 +153,20 @@ bool Commander::str2int (const char* s, int& i, int base)
bool Commander::connect()
{
   auto ret = _sock.connect("127.0.0.1", 7878);
   _sock.setTimeout(1);
   _sock.setTimeout(3);
   return ret;
}


bool Commander::getToken()
{
    if (!_sock.send(generateJSON(MSG::getToken))) 
    if (!_sock.send(generateJSON(Codes::MsgId::GetToken))) 
        return false;
    
    // Get response
    DynamicJsonDocument json(JSON_OBJECT_SIZE(3) + 20);
    if (!getJSON(json, MSG::getToken))
    //DynamicJsonDocument json(JSON_OBJECT_SIZE(3) + 20);
    DynamicJsonDocument json(JSON_OBJECT_SIZE(5) + 50);
    if (!getJSON(json, Codes::MsgId::GetToken))
        return false;
    
    string key = "param";
@@ -141,28 +181,30 @@ bool Commander::getToken()
}


bool Commander::setISO(Commander::ISO iso)
bool Commander::setISO(Codes::ISO iso)
{
    if (!_sock.send(generateJSON(MSG::setISO, (int)iso))) 
    if (!_sock.send(generateJSON(Codes::MsgId::SetISO, (int)iso))) 
        return false;
    
    // Get response
    DynamicJsonDocument json(JSON_OBJECT_SIZE(3) + 20);
    if (!getJSON(json, MSG::setISO))
    //DynamicJsonDocument json(JSON_OBJECT_SIZE(3) + 20);
    DynamicJsonDocument json(JSON_OBJECT_SIZE(5) + 50);
    if (!getJSON(json, Codes::MsgId::SetISO))
        return false;
    
    return true;
}


bool Commander::setSpeed(Commander::Speed speed)
bool Commander::setSpeed(Codes::Speed speed)
{    
    if (!_sock.send(generateJSON(MSG::setSpeed, (int)speed))) 
    if (!_sock.send(generateJSON(Codes::MsgId::SetSpeed, (int)speed))) 
        return false;
    
    // Get response
    DynamicJsonDocument json(JSON_OBJECT_SIZE(3) + 20);
    if (!getJSON(json, MSG::setSpeed))
    //DynamicJsonDocument json(JSON_OBJECT_SIZE(3) + 20);
    DynamicJsonDocument json(JSON_OBJECT_SIZE(5) + 50);
    if (!getJSON(json, Codes::MsgId::SetSpeed))
        return false;
    
    return true;
@@ -171,28 +213,22 @@ bool Commander::setSpeed(Commander::Speed speed)

bool Commander::shoot()
{
    if (!_sock.send(generateJSON(MSG::shoot)))
    if (!_sock.send(generateJSON(Codes::MsgId::Shoot)))
        return false;
    
    
    // await "capture was enqueued"
    DynamicJsonDocument json(JSON_OBJECT_SIZE(2) + 20);
    if (!getJSON(json, MSG::shoot))
    //DynamicJsonDocument json(JSON_OBJECT_SIZE(2) + 20);
    DynamicJsonDocument json(JSON_OBJECT_SIZE(5) + 50);
    if (!getJSON(json, Codes::MsgId::Shoot))
        return false;
    
    // await "capture has finished"
    json = DynamicJsonDocument(JSON_OBJECT_SIZE(9) + 140);
    if (!getJSON(json, MSG::imgCaptured, 128))
        return false;
    
    string key = "msg_id";
    if (!json.containsKey(key) || !json[key].is<int>() || json[key] != (int)MSG::imgCaptured)
    {
            cerr << "Error: unexpected JSON response: \"" << key << "\" = " << json[key] << endl;
    if (!getJSON(json, Codes::MsgId::ImgCaptured, Codes::Rval::NotificationOk))
        return false;
    }
    
    key = "param";
    string key = "param";
    if (!json.containsKey(key) || !json[key].is<string>())
    {
            cerr << "Error: unexpected JSON response: \"" << key << "\" = " << json[key] << endl;
+7 −56
Original line number Diff line number Diff line
@@ -8,81 +8,32 @@

#include "tcpSocket.h"
#include "customReader.h"
#include "codes.h"


class Commander {
public:
    
    enum class ISO
    {
        Auto = 0,
        I_50 = 50,
        I_100 = 100,
        I_200 = 2,
        I_400 = 400,
        ISO_800 = 800,
        ISO_1600 = 1600
    };
    
    enum class Speed
    {
        Auto = 0,
        
        S_1_6400 = 32768 + 6400,
        S_1_3200 = 32768 + 3200,
        S_1_2000 = 32768 + 2000,
        S_1_1000 = 32768 + 1000,
        S_1_500 = 32768 + 500,
        S_1_240 = 32768 + 240,
        S_1_120 = 32768 + 120,
        S_1_60 = 32768 + 60,
        S_1_30 = 32768 + 30,
        S_1_15 = 32768 + 15,
        S_1_8 = 32768 + 8,
        S_1_4 = 32768 + 4,
        
        S_1 = 1,
        S_2 = 2,
        S_4 = 4,
        S_8 = 8,
        S_12 = 12,
        S_16 = 16,
        S_20 = 20,
        S_24 = 24,
        S_28 = 28,
        S_32 = 32
    };
    
    
    Commander();
    bool connect();
    bool getToken();
    bool setISO(ISO iso);
    bool setSpeed(Speed speed);
    bool setISO(Codes::ISO iso);
    bool setSpeed(Codes::Speed speed);
    bool shoot();
    void close();
    

private:
    enum class MSG
    {
        getToken = 257,
        shoot = 4864,
        setSpeed = 5171,
        setISO = 5172,
        
        imgCaptured = 8193
    };
    
    int _token;
    TcpSocket _sock;
    CustomReader _reader;

    bool getJSON(DynamicJsonDocument& json, MSG expected_msg_id, int expected_rval = 0);
    bool getJSON(DynamicJsonDocument& json, Codes::MsgId expected_msg_id, Codes::Rval expected_rval = Codes::Rval::CommandOk);
    void handleMsgId(DynamicJsonDocument& json);
    static bool str2int (const char* s, int& i, int base = 0);
    
    std::string generateJSON(MSG msg);
    std::string generateJSON(MSG msg, int param);
    std::string generateJSON(Codes::MsgId msg);
    std::string generateJSON(Codes::MsgId msg, int param);
    
};

+2 −6
Original line number Diff line number Diff line
#include <iostream>
#include <string>
#include "commander.h"

using namespace std;
@@ -12,15 +11,12 @@ int main(int argc , char *argv[])
            && cout << "===== Connected =====\n\n" &&
    comm.getToken()
            && cout << "====== Token OK =====\n\n" &&
    comm.setISO(Commander::ISO::I_50)
    comm.setISO(Codes::ISO::I50)
            && cout << "====== ISO set ======\n\n" &&
            
    comm.setSpeed(Commander::Speed::S_1_240)
    comm.setSpeed(Codes::Speed::S1_120)
            && cout << "===== Speed set =====\n\n" &&
            
    comm.shoot()
            && cout << "=== Picture taken ===\n\n";
                          
    comm.close();
    //cout << "=== Socket closed ===\n";
}
+1 −0
Original line number Diff line number Diff line
#include "tcpSocket.h"
#include <iostream>

using namespace std;

Loading