1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "dmtAsyncData.h"
18#include "dm_tree_util.h"
19#include "dmt.hpp"
20#include "dmMemory.h"
21#include "xpl_Logger.h"
22
23static SYNCML_DM_RET_STATUS_T dmtBuildData(const DMT_DATA_T * pData, DmtData & oDmtData)
24{
25
26    SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
27    if (  pData == NULL )
28    {
29        oDmtData = DmtData();
30    }
31    else
32        switch ( pData->meta_format )
33        {
34          case SYNCML_DM_DATAFORMAT_STRING:
35          case SYNCML_DM_DATAFORMAT_FLOAT:
36          case SYNCML_DM_DATAFORMAT_TIME:
37          case SYNCML_DM_DATAFORMAT_DATE:
38              res = oDmtData.SetString(pData->data.str_value, pData->meta_format);
39              break;
40
41          case SYNCML_DM_DATAFORMAT_INT:
42              res = oDmtData.SetInt(pData->data.int_value);
43              break;
44
45          case SYNCML_DM_DATAFORMAT_BOOL:
46              res = oDmtData.SetBoolean((BOOLEAN)pData->data.int_value);
47              break;
48
49          case SYNCML_DM_DATAFORMAT_BIN:
50              res = oDmtData.SetBinary(pData->data.bin.bin_value,pData->data.bin.len_bin_data);
51              break;
52
53          default:
54              oDmtData = DmtData();
55              break;
56       }
57    return res;
58
59}
60
61
62static SYNCML_DM_RET_STATUS_T dmtBuildMap(const DMT_LEAF_CHILDREN_DATA_T* pData, DMMap<DMString, DmtData> & oMapNodes)
63{
64    SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
65
66    if ( pData )
67    {
68        for (int index = 0; index<pData->num_children; index++)
69        {
70            DmtData oData;
71            res = dmtBuildData((DMT_DATA_T*)&pData->pData[index],oData);
72            if ( res == SYNCML_DM_SUCCESS )
73                oMapNodes.put(DMString(pData->ppChildren[index]),oData);
74            else
75                break;
76        }
77    }
78    else
79        return SYNCML_DM_FAIL;
80
81    return res;
82}
83
84
85
86static void dmtFreeCharPtr(CPCHAR str)
87{
88    char * ptr = (char*)str;
89    if ( ptr )
90        DmFreeMem(ptr);
91}
92
93
94static void dmtFreeBytePtr(const UINT8 * byte)
95{
96    UINT8 * ptr = (UINT8*)byte;
97    if ( ptr )
98        DmFreeMem(ptr);
99}
100
101static void dmtFreeDataStruct(DMT_DATA_T * pData)
102{
103    if ( pData == NULL )
104        return;
105
106    switch ( pData->meta_format )
107    {
108        case SYNCML_DM_DATAFORMAT_STRING:
109        case SYNCML_DM_DATAFORMAT_FLOAT:
110        case SYNCML_DM_DATAFORMAT_TIME:
111        case SYNCML_DM_DATAFORMAT_DATE:
112            dmtFreeCharPtr(pData->data.str_value);
113            break;
114
115        case SYNCML_DM_DATAFORMAT_BIN:
116            dmtFreeBytePtr(pData->data.bin.bin_value);
117            break;
118    }
119    memset(pData,0,sizeof(DMT_DATA_T));
120}
121
122
123SYNCML_DM_RET_STATUS_T DMPrincipalMessage::set(CPCHAR szPrincipal,
124                                                UINT32 messageID,
125                                                UINT32 pUserData)
126{
127    DMAsyncMessage::set(messageID,pUserData);
128    principal.assign(szPrincipal);
129    if ( principal.getName() == NULL )
130    {
131        return SYNCML_DM_DEVICE_FULL;
132    }
133    return SYNCML_DM_SUCCESS;
134}
135
136
137
138SYNCML_DM_RET_STATUS_T DMGetSubTreeMessage::set(CPCHAR szPrincipal,
139                                                CPCHAR subtreeRoot,
140                                                SYNCML_DM_TREE_LOCK_TYPE_T nLockType,
141                                                DMT_CallbackGetTree callback,
142                                                UINT32 messageID,
143                                                UINT32 pUserData)
144{
145    SYNCML_DM_RET_STATUS_T res;
146    res = DMPrincipalMessage::set(szPrincipal,messageID,pUserData);
147    if ( res == SYNCML_DM_SUCCESS )
148    {
149        if ( subtreeRoot )
150        {
151            this->subtreeRoot = subtreeRoot;
152            if ( subtreeRoot[0] && this->subtreeRoot == NULL )
153            {
154                return SYNCML_DM_DEVICE_FULL;
155            }
156        }
157    }
158    this->nLockType = nLockType;
159    this->callback = callback;
160    return res;
161}
162
163
164
165SYNCML_DM_RET_STATUS_T DMScriptMessage::set(CPCHAR szPrincipal,
166                                            const UINT8 * buf,
167                                            INT32 len,
168                                            BOOLEAN isWBXML,
169                                            UINT32 messageID,
170                                            UINT32 pUserData)
171{
172    SYNCML_DM_RET_STATUS_T res;
173    res = DMPrincipalMessage::set(szPrincipal,messageID,pUserData);
174    if ( res == SYNCML_DM_SUCCESS )
175    {
176        this->buf.assign(buf,len);
177        if ( this->buf.getBuffer() == NULL )
178        {
179            return SYNCML_DM_DEVICE_FULL;
180        }
181    }
182    this->isWBXML = isWBXML;
183    return res;
184}
185
186
187SYNCML_DM_RET_STATUS_T DMProcessScriptMessage::set(CPCHAR szPrincipal,
188                                                   const UINT8 * buf,
189                                                   INT32 len,
190                                                   BOOLEAN isWBXML,
191                                                   DMT_CallbackProcessScript callback,
192                                                   UINT32 messageID,
193                                                   UINT32 pUserData)
194{
195    this->callback = callback;
196    return DMScriptMessage::set(szPrincipal,buf,len,isWBXML,messageID,pUserData);
197}
198
199
200SYNCML_DM_RET_STATUS_T DMBootstrapMessage::set(CPCHAR szPrincipal,
201                                               const UINT8 * buf,
202                                               INT32 len,
203                                               BOOLEAN isWBXML,
204                                               BOOLEAN isProcess,
205                                               DMT_CallbackBootstrap callback,
206                                               UINT32 messageID,
207                                               UINT32 pUserData)
208{
209    this->callback = callback;
210    this->isProcess = isProcess;
211    return DMScriptMessage::set(szPrincipal,buf,len,isWBXML,messageID,pUserData);
212}
213
214
215
216SYNCML_DM_RET_STATUS_T DMStartServerSessionMessage::set(CPCHAR szPrincipal,
217                                                        const DMT_SESSION_PROP_T * pSessionProp,
218                                                        DMT_CallbackStatusCode callback,
219                                                        UINT32 messageID,
220                                                        UINT32 pUserData)
221{
222    sessionProp.setWBXML(pSessionProp->isWBXML);
223
224    if ( pSessionProp->direction == SYNCML_DM_SERVER_INITIATED_SESSION )
225       sessionProp.setSessionID(pSessionProp->sessionID);
226    if ( pSessionProp->num_alerts )
227    {
228        if ( !pSessionProp->alerts )
229            return SYNCML_DM_INVALID_PARAMETER;
230        for (INT32 i=0; i<pSessionProp->num_alerts; i++)
231        {
232            DmtFirmAlert alert;
233            SYNCML_DM_RET_STATUS_T res;
234            INT32 count;
235
236            res = alert.setAlertType(((pSessionProp->alerts)+i)->strAlertType);
237            if ( res != SYNCML_DM_SUCCESS )
238                return res;
239
240            res = alert.setAlertFormat(((pSessionProp->alerts)+i)->strAlertFormat);
241            if ( res != SYNCML_DM_SUCCESS )
242                return res;
243
244            res = alert.setAlertMark(((pSessionProp->alerts)+i)->strAlertMark);
245            if ( res != SYNCML_DM_SUCCESS )
246                return res;
247
248            res = alert.setResultData(((pSessionProp->alerts)+i)->strResultData);
249            if ( res != SYNCML_DM_SUCCESS )
250                return res;
251
252            res = alert.setCorrelator(((pSessionProp->alerts)+i)->strCorrelator);
253            if ( res != SYNCML_DM_SUCCESS )
254                return res;
255
256            if ( ((pSessionProp->alerts)+i)->strPackageURI != NULL )
257            {
258	            res = alert.setPackageURI(((pSessionProp->alerts)+i)->strPackageURI);
259	            if ( res != SYNCML_DM_SUCCESS )
260	                return res;
261            	}
262
263            count = sessionProp.addFirmAlert(alert);
264            if ( count != i+1 )
265                return SYNCML_DM_DEVICE_FULL;
266        }
267    }
268    this->callback = callback;
269    return DMPrincipalMessage::set(szPrincipal,messageID,pUserData);
270}
271
272
273
274
275SYNCML_DM_RET_STATUS_T DMProcessNotificationMessage::set(CPCHAR szPrincipal,
276                                                         const UINT8 * buf,
277                                                         INT32 len,
278                                                         DMT_CallbackProcessNotification callback,
279                                                         UINT32 messageID,
280                                                         UINT32 pUserData)
281{
282    SYNCML_DM_RET_STATUS_T res;
283    res = DMPrincipalMessage::set(szPrincipal,messageID,pUserData);
284    if ( res == SYNCML_DM_SUCCESS )
285    {
286        this->buf.assign(buf,len);
287        if ( this->buf.getBuffer() == NULL )
288        {
289            return SYNCML_DM_DEVICE_FULL;
290        }
291    }
292    this->callback = callback;
293    return res;
294}
295
296
297SYNCML_DM_RET_STATUS_T DMTreeMessage::set(DMT_H_TREE htree,
298                                           CPCHAR path,
299                                           UINT32 messageID,
300                                           UINT32 pUserData)
301{
302    DMAsyncMessage::set(messageID,pUserData);
303    if ( path )
304    {
305        this->path = path;
306        if ( path[0] && this->path == NULL )
307        {
308            return SYNCML_DM_DEVICE_FULL;
309        }
310    }
311    this->htree = htree;
312    return SYNCML_DM_SUCCESS;
313}
314
315
316
317SYNCML_DM_RET_STATUS_T DMGetNodeMessage::set(DMT_H_TREE htree,
318                                             CPCHAR path,
319                                             DMT_CallbackGetNode callback,
320                                             UINT32 messageID,
321                                             UINT32 pUserData)
322{
323    this->callback = callback;
324    return DMTreeMessage::set(htree,path,messageID,pUserData);
325}
326
327
328SYNCML_DM_RET_STATUS_T DMTreeNodeMessage::set(DMT_H_TREE htree,
329                                                CPCHAR path,
330                                                CPCHAR str,
331                                                DMT_CallbackStatusCode callback,
332                                                UINT32 messageID,
333                                                UINT32 pUserData)
334{
335    SYNCML_DM_RET_STATUS_T res;
336    res = DMTreeMessage::set(htree,path,messageID,pUserData);
337    if ( res == SYNCML_DM_SUCCESS )
338    {
339        if ( str )
340        {
341            this->str = str;
342            if ( str[0] && this->str == NULL )
343            {
344                return SYNCML_DM_DEVICE_FULL;
345            }
346        }
347        this->callback = callback;
348    }
349    return res;
350}
351
352
353
354SYNCML_DM_RET_STATUS_T DMCreateLeafNodeMessage::set(DMT_H_TREE htree,
355                                                    CPCHAR path,
356                                                    const DMT_DATA_T* data,
357                                                    DMT_CallbackStatusCode callback,
358                                                    UINT32 messageID,
359                                                    UINT32 pUserData)
360{
361    SYNCML_DM_RET_STATUS_T res;
362    this->callback = callback;
363    res = DMTreeMessage::set(htree,path,messageID,pUserData);
364    if ( res == SYNCML_DM_SUCCESS )
365        res = dmtBuildData(data, this->data);
366    return res;
367}
368
369
370SYNCML_DM_RET_STATUS_T DMGetChildNodeNamesMessage::set(DMT_H_TREE htree,
371                                                       CPCHAR path,
372                                                       DMT_CallbackGetChildNodeNames callback,
373                                                       UINT32 messageID,
374                                                       UINT32 pUserData)
375{
376    this->callback = callback;
377    return DMTreeMessage::set(htree,path,messageID,pUserData);
378}
379
380
381SYNCML_DM_RET_STATUS_T  DMGetChildValuesMapMessage::set(DMT_H_TREE htree,
382                                                        CPCHAR path,
383                                                        DMT_CallbackGetChildValuesMap callback,
384                                                        UINT32 messageID,
385                                                        UINT32 pUserData)
386{
387    this->callback = callback;
388    return DMTreeMessage::set(htree,path,messageID,pUserData);
389}
390
391
392SYNCML_DM_RET_STATUS_T DMSetChildValuesMapMessage::set(DMT_H_TREE htree,
393                                                       CPCHAR path,
394                                                       const DMT_LEAF_CHILDREN_DATA_T*  data,
395                                                       DMT_CallbackStatusCode callback,
396                                                       UINT32 messageID,
397                                                       UINT32 pUserData)
398{
399    SYNCML_DM_RET_STATUS_T res;
400    this->callback = callback;
401    res = DMTreeMessage::set(htree,path,messageID,pUserData);
402    if ( res == SYNCML_DM_SUCCESS )
403      res = dmtBuildMap(data, this->data);
404    return res;
405}
406
407
408SYNCML_DM_RET_STATUS_T DMSetValueMessage::set(DMT_H_NODE hnode,
409                                              const DMT_DATA_T* data,
410                                              DMT_CallbackStatusCode callback,
411                                              UINT32 messageID,
412                                              UINT32 pUserData)
413{
414      DMAsyncMessage::set(messageID,pUserData);
415      this->hnode = hnode;
416      this->callback = callback;
417      return dmtBuildData(data, this->data);
418}
419
420
421
422SYNCML_DM_RET_STATUS_T DMNodeMessage::set(DMT_H_NODE hnode,
423                                          CPCHAR str,
424                                          DMT_CallbackStatusCode callback,
425                                          UINT32 messageID,
426                                          UINT32 pUserData)
427{
428    DMAsyncMessage::set(messageID,pUserData);
429    this->hnode = hnode;
430    this->callback = callback;
431    if ( str )
432    {
433        this->str = str;
434        if ( str[0] && this->str == NULL )
435        {
436            return SYNCML_DM_DEVICE_FULL;
437        }
438    }
439    return SYNCML_DM_SUCCESS;
440}
441
442
443SYNCML_DM_RET_STATUS_T DMExecuteMessage::set(DMT_H_NODE hnode,
444                                              CPCHAR params,
445                                              DMT_CallbackExecute callback,
446                                              UINT32 messageID,
447                                              UINT32 pUserData)
448{
449    DMAsyncMessage::set(messageID,pUserData);
450    this->hnode = hnode;
451    this->callback = callback;
452    this->params = params;
453    if ( params )
454    {
455        if ( params[0] && this->params == NULL )
456        {
457            return SYNCML_DM_DEVICE_FULL;
458        }
459    }
460    return SYNCML_DM_SUCCESS;
461}
462
463
464void DMT_Free_GetChildNodeNamesStruct(DMT_CALLBACK_STRUCT_GET_CHILDNODE_NAMES_T *pStruct)
465{
466    if ( pStruct == NULL )
467        return;
468
469    if ( pStruct->ppChildren )
470    {
471        for (INT32 index=0; index<pStruct->num_children; index++)
472        {
473            if ( pStruct->ppChildren[index] )
474                dmtFreeCharPtr(pStruct->ppChildren[index]);
475        }
476        char ** ptr = (char**)pStruct->ppChildren;
477        DmFreeMem(ptr);
478    }
479    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_GET_CHILDNODE_NAMES_T));
480}
481
482
483void DMT_Free_GetChildValuesStruct(DMT_CALLBACK_STRUCT_GET_CHILDVALUES_MAP_T *pStruct)
484{
485
486    if ( pStruct == NULL )
487        return;
488
489    if ( pStruct->data.ppChildren )
490    {
491        for (INT32 index=0; index<pStruct->data.num_children; index++)
492        {
493            if ( pStruct->data.ppChildren[index] )
494                dmtFreeCharPtr(pStruct->data.ppChildren[index]);
495        }
496        char ** ptr = (char**)pStruct->data.ppChildren;
497        DmFreeMem(ptr);
498    }
499
500    if ( pStruct->data.pData )
501    {
502       for (INT32 index=0; index<pStruct->data.num_children; index++)
503       {
504            dmtFreeDataStruct((DMT_DATA_T*)&pStruct->data.pData[index]);
505       }
506       DMT_DATA_T * ptr = (DMT_DATA_T*)(pStruct->data.pData);
507       DmFreeMem(ptr);
508    }
509    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_GET_CHILDVALUES_MAP_T));
510
511
512}
513
514void DMT_Free_GetAttributesStruct(DMT_CALLBACK_STRUCT_GET_ATTRIBUTES_T *pStruct)
515{
516    if ( pStruct == NULL )
517        return;
518
519    dmtFreeCharPtr(pStruct->attributes.name);
520    dmtFreeCharPtr(pStruct->attributes.format);
521    dmtFreeCharPtr(pStruct->attributes.title);
522    dmtFreeCharPtr(pStruct->attributes.type);
523    dmtFreeCharPtr(pStruct->attributes.acl);
524
525    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_GET_ATTRIBUTES_T));
526}
527
528
529void DMT_Free_GetValueStruct(DMT_CALLBACK_STRUCT_GET_VALUE_T *pStruct)
530{
531    if ( pStruct == NULL )
532        return;
533
534    dmtFreeDataStruct(&pStruct->data);
535    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_GET_VALUE_T));
536
537}
538
539void DMT_Free_ExecuteStruct(DMT_CALLBACK_STRUCT_EXECUTE_T *pStruct)
540{
541    if ( pStruct == NULL )
542        return;
543
544    dmtFreeCharPtr(pStruct->result);
545    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_EXECUTE_T));
546
547}
548
549
550void DMT_Free_ProcessScriptStruct(DMT_CALLBACK_STRUCT_PROCESS_SCRIPT_T *pStruct)
551{
552    if ( pStruct == NULL )
553        return;
554
555    dmtFreeCharPtr(pStruct->result);
556    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_PROCESS_SCRIPT_T));
557
558}
559
560void DMT_Free_BootstrapStruct(DMT_CALLBACK_STRUCT_BOOTSTRAP_T *pStruct)
561{
562    if ( pStruct == NULL )
563        return;
564
565    dmtFreeCharPtr(pStruct->serverID);
566    memset(pStruct,0,sizeof(DMT_CALLBACK_STRUCT_BOOTSTRAP_T));
567
568}
569
570void DMT_Free_ProcessNotificationStruct(DMT_CALLBACK_STRUCT_PROCESS_NOTIFICATION_T *pStruct)
571{
572    if ( pStruct == NULL )
573        return;
574
575    dmtFreeCharPtr(pStruct->notification.serverID);
576    memset(pStruct,0,sizeof(DMT_NOTIFICATION_T));
577}
578