File: AGClientProcessor.h

package info (click to toggle)
agsync 0.2-pre-9
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,044 kB
  • ctags: 1,183
  • sloc: ansic: 9,979; sh: 8,390; makefile: 86
file content (228 lines) | stat: -rw-r--r-- 8,741 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/* The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Mobile Application Link.
 *
 * The Initial Developer of the Original Code is AvantGo, Inc.
 * Portions created by AvantGo, Inc. are Copyright (C) 1997-1999
 * AvantGo, Inc. All Rights Reserved.
 *
 * Contributor(s):
 */

/*
    The AGClientProcessor is able to connect and send logon commands to a
    MAL server. It hides the complexity of dealing with the network in a
    non-blocking manner. 

    You configure a AGClientProcessor with the appropriate information needed
    to connect to a specific server, ie servername, port, username, etc.

    Sometimes the logon process involves sending records up to the server. In
    this case, there is a callback function that the AGClientProcessor will
    make to ask for the records. The caller is responsible for properly
    handling these requests through the AGGetNextModifiedRecordFunc and
    AGGetNextRecordFunc functions. 

    Additionally, the AGClientProcessor has no knowledge of the commands that
    are being sent from the server. It does have knowledge of the general format
    commands so it can get them properly off the network, but will send
    this data to another callback, AGPerformCommandFunc, to actually perform the
    command action. The return value of this callback determines if the 
    AGClientProcessor continues processing the next command.

*/

#ifndef __AGCLIENTPROCESSOR_H__
#define __AGCLIENTPROCESSOR_H__

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include <AGTypes.h>
#include <AGSyncProcessor.h>
#include <AGBufferWriter.h>
#include <AGBufferReader.h>
#include <AGMsg.h>
#include <AGReader.h>
#include <AGServerConfig.h>
#include <AGDeviceInfo.h>
#include <AGDBConfig.h>
#include <AGRecord.h>
#include <AGLocationConfig.h>
    
typedef enum {
    /* Processor has completed the last requested action, or has nothing to do */
    AGCLIENT_IDLE = 0,
    /* Processor still has work to do to complete the last action */
    AGCLIENT_CONTINUE,
    /* An error has occured during the processing, check the errStringId */
    AGCLIENT_ERR
} AGClientProcessResult;

/* These are returned by the callbacks
 to describe the error encountered.*/
typedef enum {
    AGCLIENT_NO_ERR = 0,
    AGCLIENT_OPEN_ERR,
    AGCLIENT_READ_ERR,
    AGCLIENT_UNKNOWN_ERR
} AGClientError;

/* 
 This function is called when the client receives a command from the server.
 It is up the the client to properly parse and interpret these command
 buffers from the server. The AGReader will contain a complete command, so
 that the read calls don't block because of the network.

 inputs -
    out - pointer that was passed into the AGClientProcessorInit() method
    commandToProcess - an AGReader containing the command buffer
 outputs - 
    errCode - if you return AGCLIENT_ERR you should fill in the errCode
 return value:
    AGCLIENT_IDLE: if there are no more commands to be handled
    AGCLIENT_CONTINUE: if there are more commands to be handled
    AGCLIENT_ERR: If there was some problem with the command 
                  and you want to stop processing commands
*/
typedef int32 (*AGPerformCommandFunc)(void *out, int32 *errCode,
                                        AGReader *commandToProcess);
/*
  This function is called prior to making the AGGetNextModifiedRecordFunc
  or AGGetNextRecordFunc calls for a particular database. 
  We will open the database and ask for all the records sequentially.
  You will not have to have mutliple databases open at a single time.
  There is no corresponding close database function. You should close
  the database when one of the readRecord functions returns no more 
  records. 
*/
typedef int32 (*AGOpenDatabaseFunc)(void *out,
                                    AGDBConfig *theDatabase, 
                                    int32 *errCode);

/* 
 These functions are called during the logon process to get records that
 need to be sent up to the server. It will be interating over the AGDBConfig
 records from the AGServerConfig structure. 

 The AGGetNextModifiedRecordFunc function will be called when the AGDBConfig
 is set to only send modified records. The AGGetNextRecordFunc will be called
 when the AGDBConfig is set to send all the records.
 
 inputs -
    out - pointer that was passed into the AGClientProcessorInit() method
 outputs -
    record - the record to be sent
    errCode - is you return AGCLIENT_ERR you should fill in the errCode
 return value:
      AGCLIENT_IDLE (+ record == NULL) when there are no more records
      AGCLIENT_CONTINUE (+ record != NULL) when there is a record
      AGCLIENT_ERR (+ record == NULL) if there is an err and you want to stop
*/
typedef int32 (*AGGetNextModifiedRecordFunc)(void *out, 
                                        AGRecord **record,
                                        int32 *errCode);
typedef int32 (*AGGetNextRecordFunc)(void *out, 
                                        AGRecord **record,
                                        int32 *errCode);

typedef int32 (*AGGetNextExpansionCommandFunc)(void *out,
                                               int32 *newCommand,
                                               int32 *commandLength,
                                               void **commandBytes);
                                            

typedef struct AGPlatformCalls {
    void *out;
    AGGetNextModifiedRecordFunc nextModifiedRecordFunc;
    AGGetNextRecordFunc nextRecordFunc;
    AGOpenDatabaseFunc openDatabaseFunc;
    AGGetNextExpansionCommandFunc nextExpansionCommandFunc;

    void *performCommandOut;
    AGPerformCommandFunc performCommandFunc;
} AGPlatformCalls;

typedef struct AGClientProcessor {
    AGServerConfig *serverInfo;
    AGDeviceInfo *deviceInfo;
    AGLocationConfig *lc;
    AGPlatformCalls *platformCalls;
    AGBool bufferCommands;
    AGBool calcBufferPass;
    AGBool bufferServerCommands;
    AGBool pingRequest;
    AGBool taskIsBufferable;
    
    int16 state;
    uint32 errStringId;

    int32 dbConfigIndex;
    AGBool sentOPEN;
    void *writeBuffer;

    AGBool writerInited;
    AGBufferWriter writer;
    AGBufferWriter *logonBufferWriter;
    AGSyncProcessor syncProcessor;
    AGBufferReader *serverCommandReader;

#ifdef _WIN32
    HANDLE threadHandle;
    HANDLE mutex;
    uint32 readIndex, writeIndex;
    AGBool finished;
    AGBufferWriter * threadWriter;
    AGBool logConnectionInfo;
    HANDLE logMutex;
    uint8 *debugBuffer;
#endif // #ifdef _WIN32

} AGClientProcessor;

ExportFunc
AGClientProcessor *AGClientProcessorNew(AGServerConfig *serverInfo,
                                        AGDeviceInfo *deviceInfo,
                                        AGLocationConfig *lc,
                                        AGPlatformCalls *platformCalls,
                                        AGBool bufferCommands,
                                        AGNetCtx *netctx);
ExportFunc
AGClientProcessor *AGClientProcessorInit(AGClientProcessor *processor, 
                                         AGServerConfig *serverInfo,
                                         AGDeviceInfo *deviceInfo,
                                         AGLocationConfig *lc,
                                         AGPlatformCalls *platformCalls,
                                         AGBool bufferCommands,
                                         AGNetCtx *netctx);

ExportFunc void AGClientProcessorSetBufferServerCommands(
                                         AGClientProcessor *processor,
                                         AGBool buffer);
    
ExportFunc void AGClientProcessorFinalize(AGClientProcessor *processor);
ExportFunc void AGClientProcessorFree(AGClientProcessor *processor);

ExportFunc void AGClientProcessorPing(AGClientProcessor *processor);
ExportFunc void AGClientProcessorSync(AGClientProcessor *processor);
ExportFunc int32 AGClientProcessorProcess(AGClientProcessor *processor);
ExportFunc
int32 AGClientProcessorBeginCommandDispatcher(AGClientProcessor *processor,
                                              void (* timeSliceFunc)(void),
                                              AGBool * cancel);
#define MAX_SYNCS (10)

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __AGCLIENTPROCESSOR_H__ */