Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
/* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved.
2
 
3
This software may be distributed and modified under the terms of the GNU
4
General Public License version 2 (GPL2) as published by the Free Software
5
Foundation and appearing in the file GPL2.TXT included in the packaging of
6
this file. Please note that GPL2 Section 2[b] requires that all works based
7
on this software must also be made publicly available under the terms of
8
the GPL2 ("Copyleft").
9
 
10
Contact information
11
-------------------
12
 
13
Circuits At Home, LTD
14
Web      :  http://www.circuitsathome.com
15
e-mail   :  support@circuitsathome.com
16
*/
17
#ifndef __PTPDPPARSER_H__
18
#define __PTPDPPARSER_H__
19
 
20
#include <inttypes.h>
21
#include <avr/pgmspace.h>
22
#include <ptpconst.h>
23
#include <ptp.h>
24
#include <valuelist.h>
25
 
26
template <class VALUE_TYPE>
27
struct PTPDevicePropValue
28
{
29
    VALUE_TYPE        valCurrent;    
30
    uint8_t           listForm;
31
    VALUE_TYPE        arrValues[3];
32
 
33
    static void SaveEnumValue(MultiValueBuffer *p, uint32_t count, void *me)
34
    {
35
          PTPDevicePropValue<VALUE_TYPE>    *dp = (PTPDevicePropValue<VALUE_TYPE>*)me;
36
 
37
          if (!dp)
38
          {
39
              PTPTRACE("NULL pointer!!!\r\n");
40
              return;
41
          }
42
          switch (dp->listForm)
43
          {
44
          case 2:
45
              if (dp->arrValues[1] != dp->valCurrent || (dp->arrValues[1] == dp->valCurrent && dp->arrValues[2] <= dp->valCurrent))
46
              {
47
                  dp->arrValues[0] = dp->arrValues[1];
48
                  dp->arrValues[1] = dp->arrValues[2];
49
                  dp->arrValues[2] = *((VALUE_TYPE*)p->pValue);
50
              }
51
              break;
52
          case 1:
53
              dp->arrValues[count] = *((VALUE_TYPE*)p->pValue);
54
              break;
55
          }
56
    };
57
};
58
 
59
template <class VALUE_TYPE>
60
class PTPDevPropParser : public PTPReadParser
61
{
62
        uint8_t                         nStage;
63
    uint8_t             enStage;
64
    uint8_t                             formFlag;
65
    MultiValueBuffer    theBuffer;
66
    uint8_t                             varBuffer[sizeof(VALUE_TYPE)];
67
    uint16_t            enLen;
68
    uint16_t            enLenCntdn;
69
 
70
        MultiByteValueParser                            valParser;
71
    PTPDevicePropValue<VALUE_TYPE>     *pDPValue;
72
 
73
        bool ParseValue         (uint8_t **pp, uint16_t *pcntdn, VALUE_TYPE&);      
74
        bool ParseEnumSingle(uint8_t **pp, uint16_t *pcntdn);      
75
 
76
    PTPListParser      enumParser;
77
 
78
    uint8_t GetDataSize();
79
 
80
public:
81
        PTPDevPropParser(PTPDevicePropValue<VALUE_TYPE> *p) :
82
        pDPValue(p),
83
                nStage(0),
84
                enStage(0),
85
                formFlag(0),
86
        enLen(0),
87
        enLenCntdn(0)
88
        {
89
        theBuffer.valueSize = sizeof(VALUE_TYPE);
90
                theBuffer.pValue = varBuffer;
91
        }
92
        virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset);
93
};
94
 
95
template <class VALUE_TYPE>
96
bool PTPDevPropParser<VALUE_TYPE>::ParseValue(uint8_t **pp, uint16_t *pcntdn, VALUE_TYPE &val)
97
{
98
    val = *((VALUE_TYPE*)*pp);
99
    (*pp)       += sizeof(VALUE_TYPE);
100
    (*pcntdn)   -= sizeof(VALUE_TYPE);
101
    return true;
102
}
103
 
104
template <class VALUE_TYPE>
105
bool PTPDevPropParser<VALUE_TYPE>::ParseEnumSingle(uint8_t **pp, uint16_t *pcntdn)
106
{
107
    switch(enStage)
108
    {
109
    case 0:
110
        enumParser.Initialize(2, sizeof(VALUE_TYPE), &theBuffer);
111
        enStage ++;
112
    case 1:
113
        if (!enumParser.Parse(pp, pcntdn, (PTP_ARRAY_EL_FUNC)&PTPDevicePropValue<VALUE_TYPE>::SaveEnumValue, pDPValue))
114
            return false;
115
        enStage = 0;
116
    } // switch
117
    return true;
118
}
119
 
120
template <class VALUE_TYPE>
121
void PTPDevPropParser<VALUE_TYPE>::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset)
122
{
123
        uint16_t        cntdn   = (uint16_t)len;
124
        uint8_t         *p      = (uint8_t*)pbuf;
125
 
126
        VALUE_TYPE      vt = 1;
127
 
128
        switch (nStage)
129
        {
130
        case 0:
131
                p       += 17;
132
                cntdn   -= 17;
133
                nStage = 1;
134
        case 1:
135
                if (!ParseValue(&p, &cntdn, vt))
136
                        return;
137
                nStage = 2;
138
        case 2:
139
                if (!ParseValue(&p, &cntdn, pDPValue->valCurrent))
140
                        return;
141
                nStage = 3;
142
        case 3:
143
                for (uint8_t i=0; i<3; i++)
144
                    pDPValue->arrValues[i] = pDPValue->valCurrent;
145
 
146
                formFlag = (*p);
147
                pDPValue->listForm = formFlag;
148
                p ++;          
149
                cntdn --;
150
                nStage = 4;
151
        case 4:
152
                if (formFlag == 1)
153
                        enumParser.Initialize(2, sizeof(VALUE_TYPE), &theBuffer, PTPListParser::modeRange);
154
                nStage = 5;
155
        case 5:
156
                if (formFlag == 1)
157
                        if (!enumParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PTPDevicePropValue<VALUE_TYPE>::SaveEnumValue, pDPValue))
158
                              return;
159
 
160
                if (formFlag == 2)
161
                        if (!ParseEnumSingle(&p, &cntdn))
162
                                return;
163
 
164
                nStage = 0;
165
        }
166
}
167
 
168
template <class VALUE_TYPE>
169
uint16_t StepUp(PTP *ptp, uint16_t prop)
170
{
171
    PTPDevicePropValue<VALUE_TYPE>  val;
172
    PTPDevPropParser<VALUE_TYPE>    prs(&val);
173
 
174
    uint16_t ret = ptp->GetDevicePropDesc(prop, &prs);
175
 
176
    if (ret != PTP_RC_OK)
177
        return ret;
178
 
179
    if (val.listForm == 2)
180
        if (val.arrValues[1] == val.valCurrent)
181
            return ptp->SetDevicePropValue(prop, (VALUE_TYPE)val.arrValues[2]);
182
 
183
    if (val.listForm == 1)
184
        if (val.valCurrent + val.arrValues[2] <= val.arrValues[1])
185
            return ptp->SetDevicePropValue(prop, (VALUE_TYPE)(val.valCurrent + val.arrValues[2]));
186
 
187
    return PTP_RC_OK;
188
}
189
 
190
template <class VALUE_TYPE>
191
uint16_t StepDown(PTP *ptp, uint16_t prop)
192
{
193
    PTPDevicePropValue<VALUE_TYPE>  val;
194
    PTPDevPropParser<VALUE_TYPE>    prs(&val);
195
 
196
    uint16_t ret = ptp->GetDevicePropDesc(prop, &prs);
197
 
198
    if (ret != PTP_RC_OK)
199
        return ret;
200
 
201
    if (val.listForm == 2)
202
    {    
203
        if (val.arrValues[1] == val.valCurrent && val.arrValues[0] < val.arrValues[1])
204
            return ptp->SetDevicePropValue(prop, (VALUE_TYPE)val.arrValues[0]);
205
 
206
        if (val.arrValues[2] == val.valCurrent)
207
            return ptp->SetDevicePropValue(prop, (VALUE_TYPE)val.arrValues[1]);
208
    }
209
    if (val.listForm == 1)
210
    {
211
        VALUE_TYPE new_val = val.valCurrent - val.arrValues[2];
212
        if (new_val >= val.arrValues[0] && new_val < val.valCurrent)
213
            return ptp->SetDevicePropValue(prop, (VALUE_TYPE)(val.valCurrent - val.arrValues[2]));
214
    }      
215
    return PTP_RC_OK;
216
}
217
 
218
template <class VALUE_TYPE, class LIST_VALUE_TYPE, const uint8_t TABLE_SIZE, const uint8_t TEXT_SIZE>
219
uint16_t GetValueTitle(PTP *ptp, uint16_t prop, const ValueTitle<LIST_VALUE_TYPE, TEXT_SIZE> *p, const char **t)
220
{
221
    VALUE_TYPE  val;
222
    uint16_t ret = ptp->GetDevicePropValue(prop, val);
223
 
224
    if (ret != PTP_RC_OK)
225
        return ret;
226
 
227
    *t = (char*)FindTitle<LIST_VALUE_TYPE, TEXT_SIZE>(TABLE_SIZE, p, (LIST_VALUE_TYPE)val);
228
    return ret;
229
}
230
 
231
template <class VALUE_TYPE, class LIST_VALUE_TYPE, const uint8_t TABLE_SIZE, const uint8_t TEXT_SIZE>
232
uint16_t PrintValueTitle(PTP *ptp, uint16_t prop, const ValueTitle<LIST_VALUE_TYPE, TEXT_SIZE> *p )
233
{
234
        const char      *title;
235
 
236
        if (GetValueTitle<LIST_VALUE_TYPE, LIST_VALUE_TYPE, TABLE_SIZE, TEXT_SIZE>(ptp, prop, p, &title) == PTP_RC_OK)
237
                Notify(title);
238
}
239
 
240
#endif // __PTPDPPARSER_H__