Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / backends / aqhbci / applayer / cbox_queue.c @ 28c57bc8

History | View | Annotate | Download (18.9 KB)

1
/***************************************************************************
2
    begin       : Mon Mar 01 2004
3
    copyright   : (C) 2018 by Martin Preuss
4
    email       : martin@libchipcard.de
5

6
 ***************************************************************************
7
 *          Please see toplevel file COPYING for license details           *
8
 ***************************************************************************/
9

    
10

    
11
#ifdef HAVE_CONFIG_H
12
# include <config.h>
13
#endif
14

    
15

    
16
#include "cbox_queue.h"
17

    
18
#include "aqhbci/admjobs/jobtan_l.h"
19

    
20
#include "aqhbci/applayer/cbox_send.h"
21
#include "aqhbci/applayer/cbox_recv.h"
22
#include "aqhbci/applayer/cbox_dialog.h"
23

    
24
#include <gwenhywfar/debug.h>
25
#include <gwenhywfar/misc.h>
26
#include <gwenhywfar/gui.h>
27

    
28
#include <assert.h>
29

    
30

    
31
/* ------------------------------------------------------------------------------------------------
32
 * forward declarations
33
 * ------------------------------------------------------------------------------------------------
34
 */
35

    
36
static AH_JOBQUEUE *_createNextQueueFromTodoList(AB_USER *user, AH_JOB_LIST *jl, uint32_t jqFlags,
37
                                                 AH_JOB_LIST *finishedJobs);
38
static int _performQueue(AH_OUTBOX_CBOX *cbox, AH_DIALOG *dlg, AH_JOBQUEUE *jq);
39
static int _performNonDialogQueues(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE_LIST *jql);
40
static int _performDialogQueue(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE *jq);
41
static void _extractMatchingQueues(AH_JOBQUEUE_LIST *jql,
42
                                   AH_JOBQUEUE_LIST *jqlWanted,
43
                                   AH_JOBQUEUE_LIST *jqlRest,
44
                                   uint32_t jqflags,
45
                                   uint32_t jqmask);
46
static void _handleQueueListError(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE_LIST *jql, const char *logStr);
47

    
48
static int _sendAndRecvDialogQueues(AH_OUTBOX_CBOX *cbox);
49
static int _sendAndRecvSelected(AH_OUTBOX_CBOX *cbox, uint32_t jqflags, uint32_t jqmask);
50
static void _handleQueueError(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE *jq, const char *logStr);
51

    
52
/* ------------------------------------------------------------------------------------------------
53
 * implementations
54
 * ------------------------------------------------------------------------------------------------
55
 */
56

    
57

    
58

    
59

    
60
int AH_OutboxCBox_SendAndRecvBox(AH_OUTBOX_CBOX *cbox)
61
{
62
  int rv;
63

    
64
  /* dialog queues */
65
  rv=_sendAndRecvDialogQueues(cbox);
66
  if (rv) {
67
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error performing dialog queues (%d)", rv);
68
    return rv;
69
  }
70

    
71
  /* non-dialog queues: unsigned, uncrypted */
72
  rv=_sendAndRecvSelected(cbox,
73
                          0,
74
                          AH_JOBQUEUE_FLAGS_ISDIALOG |
75
                          AH_JOBQUEUE_FLAGS_SIGN |
76
                          AH_JOBQUEUE_FLAGS_CRYPT);
77
  if (rv) {
78
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error performing queues (-S, -C: %d)", rv);
79
    return rv;
80
  }
81

    
82
  /* non-dialog queues: unsigned, crypted */
83
  rv=_sendAndRecvSelected(cbox,
84
                          AH_JOBQUEUE_FLAGS_CRYPT,
85
                          AH_JOBQUEUE_FLAGS_ISDIALOG |
86
                          AH_JOBQUEUE_FLAGS_SIGN |
87
                          AH_JOBQUEUE_FLAGS_CRYPT);
88
  if (rv) {
89
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error performing queues (-S, +C: %d)", rv);
90
    return rv;
91
  }
92

    
93
  /* non-dialog queues: signed, uncrypted */
94
  rv=_sendAndRecvSelected(cbox,
95
                          AH_JOBQUEUE_FLAGS_SIGN,
96
                          AH_JOBQUEUE_FLAGS_ISDIALOG |
97
                          AH_JOBQUEUE_FLAGS_SIGN |
98
                          AH_JOBQUEUE_FLAGS_CRYPT);
99
  if (rv) {
100
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error performing queues (+S, -C: %d)", rv);
101
    return rv;
102
  }
103

    
104
  /* non-dialog queues: signed, crypted */
105
  rv=_sendAndRecvSelected(cbox,
106
                          AH_JOBQUEUE_FLAGS_SIGN |
107
                          AH_JOBQUEUE_FLAGS_CRYPT,
108
                          AH_JOBQUEUE_FLAGS_ISDIALOG |
109
                          AH_JOBQUEUE_FLAGS_SIGN |
110
                          AH_JOBQUEUE_FLAGS_CRYPT);
111
  if (rv) {
112
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error performing queues (+S, +C: %d)", rv);
113
    return rv;
114
  }
115

    
116
  return 0;
117
}
118

    
119

    
120

    
121
/* NOTE: frees jq! */
122
int _performQueue(AH_OUTBOX_CBOX *cbox, AH_DIALOG *dlg, AH_JOBQUEUE *jq)
123
{
124
  int rv;
125
  AB_USER *user;
126
  AH_JOB_LIST *finishedJobs;
127

    
128
  user=AH_OutboxCBox_GetUser(cbox);
129
  finishedJobs=AH_OutboxCBox_GetFinishedJobs(cbox);
130

    
131
  for (;;) {
132
    AH_JOBQUEUE *jqTodo;
133
    AH_JOB_LIST *jl;
134

    
135
    jl=AH_JobQueue_TakeJobList(jq);
136
    assert(jl);
137

    
138
    jqTodo=_createNextQueueFromTodoList(user, jl, AH_JobQueue_GetFlags(jq), finishedJobs);
139
    AH_Job_List_free(jl);
140
    AH_JobQueue_free(jq);
141
    if (jqTodo==NULL) {
142
      DBG_INFO(AQHBCI_LOGDOMAIN, "No more jobs left");
143
      break;
144
    }
145
    jq=jqTodo;
146

    
147
    /* jq now contains all jobs to be executed */
148
    rv=AH_OutboxCBox_SendAndRecvQueue(cbox, dlg, jq);
149
    if (rv) {
150
      _handleQueueError(cbox, jq, "Error performing queue"); /* frees jobQueue */
151
      return rv;
152
    } /* if error */
153
  } /* for */
154

    
155
  return 0;
156
}
157

    
158

    
159

    
160
AH_JOBQUEUE *_createNextQueueFromTodoList(AB_USER *user, AH_JOB_LIST *jl, uint32_t jqFlags, AH_JOB_LIST *finishedJobs)
161
{
162
  AH_JOB *j;
163
  AH_JOBQUEUE *jqTodo;
164

    
165
  jqTodo=AH_JobQueue_new(user);
166
  /* copy some flags */
167
  jqFlags&=~(AH_JOBQUEUE_FLAGS_CRYPT |
168
             AH_JOBQUEUE_FLAGS_SIGN |
169
             AH_JOBQUEUE_FLAGS_NOSYSID |
170
             AH_JOBQUEUE_FLAGS_NOITAN);
171
  AH_JobQueue_SetFlags(jqTodo, (jqFlags&AH_JOBQUEUE_FLAGS_COPYMASK));
172

    
173
  while ((j=AH_Job_List_First(jl))) {
174
    AH_Job_List_Del(j);
175

    
176
    if (AH_Job_GetStatus(j)==AH_JobStatusAnswered) {
177
      DBG_INFO(AQHBCI_LOGDOMAIN, "Job status \"answered\", checking whether it needs to be re-enqueued");
178
      /* prepare job for next message
179
       * (if attachpoint or multi-message job)
180
       */
181
      AH_Job_PrepareNextMessage(j);
182
      if (AH_Job_GetFlags(j) & AH_JOB_FLAGS_HASMOREMSGS) {
183
        DBG_NOTICE(AQHBCI_LOGDOMAIN, "Requeueing job");
184
        /* we shall redo this job */
185
        if (AH_JobQueue_AddJob(jqTodo, j)!=AH_JobQueueAddResultOk) {
186
          DBG_ERROR(AQHBCI_LOGDOMAIN, "Job could not be re-added to queue, SNH!");
187
          AH_Job_Log(j, GWEN_LoggerLevel_Error, "Could not re-enqueue job");
188
          AH_Job_SetStatus(j, AH_JobStatusError);
189
        }
190
        else {
191
          AH_Job_Log(j, GWEN_LoggerLevel_Info, "Job re-enqueued (multi-message job)");
192
          j=NULL; /* mark that this job has been dealt with */
193
        }
194
      } /* if more messages */
195
      else {
196
        DBG_NOTICE(AQHBCI_LOGDOMAIN, "Job has no messages left, not re-enqueing");
197
      }
198
    } /* if status "answered" */
199

    
200
    else if (AH_Job_GetStatus(j)==AH_JobStatusEnqueued) {
201
      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Job status \"enqueued\", trying to re-enqueue (TODO: Is this really used?)");
202
      if (AH_JobQueue_AddJob(jqTodo, j)!=AH_JobQueueAddResultOk) {
203
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Job could not be re-added to queue, SNH!");
204
        AH_Job_SetStatus(j, AH_JobStatusError);
205
        AH_Job_Log(j, GWEN_LoggerLevel_Error, "Could not enqueue job");
206
      }
207
      else {
208
        AH_Job_Log(j, GWEN_LoggerLevel_Info, "Job enqueued (2)");
209
        j=NULL; /* mark that this job has been dealt with */
210
      }
211
    } /* if status "enqueued" */
212

    
213
    else {
214
      DBG_WARN(AQHBCI_LOGDOMAIN, "Bad status \"%s\" (%d)",
215
               AH_Job_StatusName(AH_Job_GetStatus(j)),
216
               AH_Job_GetStatus(j));
217
      if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Debug)
218
        AH_Job_Dump(j, stderr, 4);
219
    }
220

    
221
    if (j) {
222
      /* move job to finished list if we still have the job */
223
      AH_Job_List_Add(j, finishedJobs);
224
    }
225
  } /* while */
226

    
227
  if (AH_JobQueue_GetCount(jqTodo)==0) {
228
    DBG_INFO(AQHBCI_LOGDOMAIN, "No jobs enqueued.");
229
    AH_JobQueue_free(jqTodo);
230
    return NULL;
231
  }
232

    
233
  return jqTodo;
234
}
235

    
236

    
237

    
238

    
239
int _performNonDialogQueues(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE_LIST *jql)
240
{
241
  AB_USER *user;
242
  AB_PROVIDER *provider;
243
  AH_DIALOG *dlg;
244
  AH_JOBQUEUE *jq;
245
  int rv=0;
246
  int i;
247
  uint32_t jqflags;
248

    
249
  user=AH_OutboxCBox_GetUser(cbox);
250
  provider=AH_OutboxCBox_GetProvider(cbox);
251

    
252
  if (AH_JobQueue_List_GetCount(jql)==0) {
253
    DBG_NOTICE(AQHBCI_LOGDOMAIN, "No queues to handle, doing nothing");
254
    AH_JobQueue_List_free(jql);
255
    return 0;
256
  }
257

    
258
  for (i=0; i<2; i++) {
259
    dlg=AH_Dialog_new(user, provider);
260
    rv=AH_Dialog_Connect(dlg);
261
    if (rv) {
262
      DBG_INFO(AQHBCI_LOGDOMAIN,
263
               "Could not begin a dialog for customer \"%s\" (%d)",
264
               AB_User_GetCustomerId(user), rv);
265
      /* finish all queues */
266
      _handleQueueListError(cbox, jql, "Could not begin dialog");
267
      AH_Dialog_free(dlg);
268
      return rv;
269
    }
270

    
271
    jq=AH_JobQueue_List_First(jql);
272
    jqflags=AH_JobQueue_GetFlags(jq);
273

    
274
    /* open dialog */
275
    rv=AH_OutboxCBox_OpenDialog(cbox, dlg, jqflags);
276
    if (rv==0)
277
      break;
278
    else if (rv<0) {
279
      DBG_INFO(AQHBCI_LOGDOMAIN, "Could not open dialog");
280
      AH_Dialog_Disconnect(dlg);
281
      /* finish all queues */
282
      _handleQueueListError(cbox, jql, "Could not open dialog");
283
      AH_Dialog_free(dlg);
284
      return rv;
285
    }
286
    else if (rv==1) {
287
      AH_Dialog_Disconnect(dlg);
288
      AH_Dialog_free(dlg);
289
      GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Info, I18N("Retrying to open dialog"));
290
    }
291
  }
292
  if (rv) {
293
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not open dialog");
294
    AH_Dialog_Disconnect(dlg);
295
    /* finish all queues */
296
    _handleQueueListError(cbox, jql, "Could not open dialog");
297
    AH_Dialog_free(dlg);
298
    return rv;
299
  }
300

    
301
  /* handle queues */
302
  rv=0;
303
  while ((jq=AH_JobQueue_List_First(jql))) {
304
    AH_JobQueue_List_Del(jq);
305
    rv=_performQueue(cbox, dlg, jq); /* frees jq */
306
    if (rv)
307
      break;
308
  } /* while */
309

    
310
  if (rv) {
311
    /* finish all remaining queues */
312
    _handleQueueListError(cbox, jql, "Could not send ");
313
    AH_Dialog_Disconnect(dlg);
314
    AH_Dialog_free(dlg);
315
    return rv;
316
  }
317

    
318
  /* close dialog */
319
  rv=AH_OutboxCBox_CloseDialog(cbox, dlg, jqflags);
320
  if (rv) {
321
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not close dialog, ignoring");
322
    /*AH_HBCI_EndDialog(cbox->hbci, dlg);
323
     return rv;*/
324
  }
325

    
326
  DBG_INFO(AQHBCI_LOGDOMAIN, "Closing connection");
327
  AH_Dialog_Disconnect(dlg);
328
  AH_Dialog_free(dlg);
329

    
330
  AH_JobQueue_List_free(jql);
331
  return 0;
332
}
333

    
334

    
335

    
336
int _performDialogQueue(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE *jq)
337
{
338
  AB_USER *user;
339
  AB_PROVIDER *provider;
340
  AH_DIALOG *dlg;
341
  int rv;
342
  uint32_t jqFlags;
343

    
344
  user=AH_OutboxCBox_GetUser(cbox);
345
  provider=AH_OutboxCBox_GetProvider(cbox);
346

    
347
  jqFlags=AH_JobQueue_GetFlags(jq);
348

    
349
  /* open connection */
350
  dlg=AH_Dialog_new(user, provider);
351
  rv=AH_Dialog_Connect(dlg);
352
  if (rv) {
353
    DBG_INFO(AQHBCI_LOGDOMAIN,
354
             "Could not begin a dialog for customer \"%s\" (%d)",
355
             AB_User_GetCustomerId(user), rv);
356
    /* finish all queues */
357
    _handleQueueError(cbox, jq, "Could not begin dialog");
358
    AH_Dialog_free(dlg);
359
    return rv;
360
  }
361

    
362
#ifdef EXTREME_DEBUGGING
363
  DBG_ERROR(AQHBCI_LOGDOMAIN, "Handling this job queue:");
364
  AH_JobQueue_Dump(jq, stderr, 2);
365
#endif
366

    
367
  if (AH_User_GetCryptMode(user)==AH_CryptMode_Pintan) {
368
    if (jqFlags & AH_JOBQUEUE_FLAGS_NOITAN) {
369
      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Not using PSD2 code: Job queue has flag NOITAN set (using single step).");
370
      AH_Dialog_SetItanMethod(dlg, 999);
371
      AH_Dialog_SetItanProcessType(dlg, 1);
372
      AH_Dialog_SetTanJobVersion(dlg, 0);
373
    }
374
    else {
375
      int selectedTanVersion;
376

    
377
      /* select iTAN mode */
378
      DBG_INFO(AQHBCI_LOGDOMAIN, "Job queue doesn't have flag NOITAN");
379
      rv=AH_OutboxCBox_SelectItanMode(cbox, dlg);
380
      if (rv) {
381
        AH_Dialog_Disconnect(dlg);
382
        AH_Dialog_free(dlg);
383
        return rv;
384
      }
385

    
386
      selectedTanVersion=AH_User_GetSelectedTanMethod(user)/1000;
387
      if (selectedTanVersion>=6) {
388
        AH_JOB *jTan;
389

    
390
        DBG_INFO(AQHBCI_LOGDOMAIN, "User-selected TAN job version is 6 or newer (%d)", selectedTanVersion);
391

    
392
        /* check for PSD2: HKTAN version 6 available? if so -> use that */
393
        jTan=AH_Job_Tan_new(provider, user, 4, 6);
394
        if (jTan) {
395
          AH_Job_free(jTan);
396
          DBG_INFO(AQHBCI_LOGDOMAIN, "TAN job version 6 is available");
397
          DBG_NOTICE(AQHBCI_LOGDOMAIN, "Using PSD2 code for dialog job");
398
          AH_JobQueue_AddFlags(jq, AH_JOBQUEUE_FLAGS_NEEDTAN);
399
          AH_Dialog_AddFlags(dlg, AH_DIALOG_FLAGS_SCA);
400
        }
401
        else {
402
          DBG_NOTICE(AQHBCI_LOGDOMAIN, "Not using PSD2 code: HKTAN version 6 not supported by the bank");
403
        }
404
      }
405
      else {
406
        DBG_NOTICE(AQHBCI_LOGDOMAIN, "Not using PSD2 code: User selected HKTAN version lesser than 6.");
407
      }
408
    }
409
  }
410

    
411
  /* handle queue */
412
  rv=_performQueue(cbox, dlg, jq);
413
  if (rv) {
414
    AH_Dialog_Disconnect(dlg);
415
    AH_Dialog_free(dlg);
416
    return rv;
417
  }
418

    
419
  /* close dialog */
420
#if 0
421
  if (AH_User_GetCryptMode(user)==AH_CryptMode_Pintan &&
422
      (jqFlags & AH_JOBQUEUE_FLAGS_NOITAN)) {
423
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Changing dialog to anonymous mode");
424
    AH_Dialog_AddFlags(dlg, AH_DIALOG_FLAGS_ANONYMOUS);
425
  }
426
#endif
427

    
428
  rv=AH_OutboxCBox_CloseDialog(cbox, dlg, jqFlags);
429
  if (rv) {
430
    AH_Dialog_Disconnect(dlg);
431
    AH_Dialog_free(dlg);
432
    return rv;
433
  }
434

    
435
  /* close connection */
436
  DBG_INFO(AQHBCI_LOGDOMAIN, "Closing connection");
437
  AH_Dialog_Disconnect(dlg);
438
  AH_Dialog_free(dlg);
439

    
440
  return 0;
441
}
442

    
443

    
444

    
445
void _extractMatchingQueues(AH_JOBQUEUE_LIST *jql,
446
                            AH_JOBQUEUE_LIST *jqlWanted,
447
                            AH_JOBQUEUE_LIST *jqlRest,
448
                            uint32_t jqflags,
449
                            uint32_t jqmask)
450
{
451
  AH_JOBQUEUE *jq;
452

    
453
  while ((jq=AH_JobQueue_List_First(jql))) {
454
    uint32_t flags;
455

    
456
    AH_JobQueue_List_Del(jq);
457
    flags=AH_JobQueue_GetFlags(jq);
458
    if ((flags^jqflags)  & jqmask)
459
      /* no match */
460
      AH_JobQueue_List_Add(jq, jqlRest);
461
    else
462
      AH_JobQueue_List_Add(jq, jqlWanted);
463
  } /* while */
464
}
465

    
466

    
467

    
468
void _handleQueueListError(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE_LIST *jql, const char *logStr)
469
{
470
  if (jql) {
471
    AH_JOBQUEUE *jq;
472

    
473
    while ((jq=AH_JobQueue_List_First(jql))) {
474
      AH_JobQueue_List_Del(jq);
475
      _handleQueueError(cbox, jq, logStr);
476
    } /* while */
477
    AH_JobQueue_List_free(jql);
478
  }
479
}
480

    
481

    
482

    
483
int _sendAndRecvDialogQueues(AH_OUTBOX_CBOX *cbox)
484
{
485
  AH_JOBQUEUE_LIST *todoQueues;
486
  AH_JOBQUEUE_LIST *jqlWanted;
487
  AH_JOBQUEUE_LIST *jqlRest;
488
  int rv;
489

    
490
  todoQueues=AH_OutboxCBox_TakeTodoQueues(cbox);
491

    
492
  jqlWanted=AH_JobQueue_List_new();
493
  jqlRest=AH_JobQueue_List_new();
494
  _extractMatchingQueues(todoQueues, jqlWanted, jqlRest, AH_JOBQUEUE_FLAGS_ISDIALOG, AH_JOBQUEUE_FLAGS_ISDIALOG);
495
  AH_JobQueue_List_free(todoQueues); /* is empty now */
496
  AH_OutboxCBox_SetTodoQueues(cbox, jqlRest);
497
  todoQueues=jqlRest;
498

    
499
  if (AH_JobQueue_List_GetCount(jqlWanted)) {
500
    AH_JOBQUEUE *jq;
501

    
502
    /* there are matching queues, handle them */
503
    while ((jq=AH_JobQueue_List_First(jqlWanted))) {
504
      AH_JobQueue_List_Del(jq);
505
      rv=_performDialogQueue(cbox, jq);
506
      if (rv) {
507
        DBG_INFO(AQHBCI_LOGDOMAIN, "Error performing queue (%d)", rv);
508
        _handleQueueListError(cbox, jqlWanted, "Could not perform dialog queue");
509
        //_handleQueueListError(cbox, todoQueues, "Could not perform dialog queue");
510
        //AH_OutboxCBox_SetTodoQueues(cbox, AH_JobQueue_List_new());
511
        return rv;
512
      }
513
    } /* while */
514
  }
515
  AH_JobQueue_List_free(jqlWanted);
516
  return 0;
517
}
518

    
519

    
520

    
521
int _sendAndRecvSelected(AH_OUTBOX_CBOX *cbox, uint32_t jqflags, uint32_t jqmask)
522
{
523
  AH_JOBQUEUE_LIST *todoQueues;
524
  AH_JOBQUEUE_LIST *jqlWanted;
525
  AH_JOBQUEUE_LIST *jqlRest;
526
  int rv;
527

    
528
  todoQueues=AH_OutboxCBox_TakeTodoQueues(cbox);
529

    
530
  jqlWanted=AH_JobQueue_List_new();
531
  jqlRest=AH_JobQueue_List_new();
532
  _extractMatchingQueues(todoQueues, jqlWanted, jqlRest, jqflags, jqmask);
533
  AH_JobQueue_List_free(todoQueues); /* is empty now */
534
  AH_OutboxCBox_SetTodoQueues(cbox, jqlRest);
535
  todoQueues=jqlRest;
536

    
537
  if (AH_JobQueue_List_GetCount(jqlWanted)) {
538
    /* there are matching queues, handle them */
539
    rv=_performNonDialogQueues(cbox, jqlWanted);
540
    if (rv<0) {
541
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Error performing queue (%d)", rv);
542
      //_handleQueueListError(cbox, todoQueues, "Error performing selected jobs");
543
      //AH_OutboxCBox_SetTodoQueues(cbox, AH_JobQueue_List_new());
544
      return rv;
545
    }
546
  } /* if matching queuees */
547
  else
548
    AH_JobQueue_List_free(jqlWanted);
549
  return 0;
550
}
551

    
552

    
553

    
554
int AH_OutboxCBox_SendAndRecvQueueNoTan(AH_OUTBOX_CBOX *cbox, AH_DIALOG *dlg, AH_JOBQUEUE *jq)
555
{
556
  int rv;
557

    
558
  rv=AH_OutboxCBox_SendQueue(cbox, dlg, jq);
559
  if (rv) {
560
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error sending queue");
561
    return rv;
562
  }
563

    
564
  AH_JobQueue_SetJobStatusOnMatch(jq, AH_JobStatusEncoded, AH_JobStatusSent);
565

    
566
  rv=AH_OutboxCBox_RecvQueue(cbox, dlg, jq);
567
  if (rv) {
568
    DBG_INFO(AQHBCI_LOGDOMAIN, "Error receiving queue response");
569
    return rv;
570
  }
571

    
572
  return 0;
573
}
574

    
575

    
576

    
577
int AH_OutboxCBox_SendAndRecvQueue(AH_OUTBOX_CBOX *cbox, AH_DIALOG *dlg, AH_JOBQUEUE *jq)
578
{
579
  int rv;
580

    
581
  if ((AH_JobQueue_GetFlags(jq) & AH_JOBQUEUE_FLAGS_NEEDTAN) &&
582
      AH_Dialog_GetItanProcessType(dlg)!=0) {
583
    DBG_DEBUG(AQHBCI_LOGDOMAIN, "TAN mode");
584
    rv=AH_OutboxCBox_SendAndReceiveQueueWithTan(cbox, dlg, jq);
585
    if (rv) {
586
      DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
587
      return rv;
588
    }
589
  }
590
  else {
591
    DBG_DEBUG(AQHBCI_LOGDOMAIN, "Normal mode");
592
    rv=AH_OutboxCBox_SendAndRecvQueueNoTan(cbox, dlg, jq);
593
    if (rv) {
594
      DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
595
      return rv;
596
    }
597
  }
598

    
599
  return 0;
600
}
601

    
602

    
603

    
604
void _handleQueueError(AH_OUTBOX_CBOX *cbox, AH_JOBQUEUE *jq, const char *logStr)
605
{
606
  AH_JOB_LIST *finishedJobs;
607
  AH_JOB *j;
608
  AH_JOB_LIST *jl;
609

    
610
  finishedJobs=AH_OutboxCBox_GetFinishedJobs(cbox);
611

    
612
  jl=AH_JobQueue_TakeJobList(jq);
613
  assert(jl);
614

    
615
  while ((j=AH_Job_List_First(jl))) {
616
    AH_Job_List_Del(j);
617
    if (AH_Job_GetStatus(j)!=AH_JobStatusAnswered) {
618
      DBG_INFO(AQHBCI_LOGDOMAIN, "Setting status of job \"%s\" to ERROR", AH_Job_GetName(j));
619
      AH_Job_SetStatus(j, AH_JobStatusError);
620
      if (logStr)
621
        AH_Job_Log(j, GWEN_LoggerLevel_Error, logStr);
622
    }
623
    AH_Job_List_Add(j, finishedJobs);
624
  }
625
  AH_Job_List_free(jl);
626
  AH_JobQueue_free(jq);
627
}
628

    
629

    
630

    
631
void AH_OutboxCBox_Finish(AH_OUTBOX_CBOX *cbox)
632
{
633
  AH_JOB_LIST *finishedJobs;
634
  AH_JOBQUEUE_LIST *todoQueues;
635
  AH_JOB_LIST *todoJobs;
636
  AH_JOBQUEUE *jq;
637

    
638
  assert(cbox);
639

    
640
  finishedJobs=AH_OutboxCBox_GetFinishedJobs(cbox);
641
  todoQueues=AH_OutboxCBox_GetTodoQueues(cbox);
642
  todoJobs=AH_OutboxCBox_GetTodoJobs(cbox);
643

    
644
  DBG_INFO(AQHBCI_LOGDOMAIN, "Finishing customer box");
645

    
646
  while ((jq=AH_JobQueue_List_First(todoQueues))) {
647
    AH_JOB_LIST *jl;
648
    AH_JOB *j;
649

    
650
    jl=AH_JobQueue_TakeJobList(jq);
651
    assert(jl);
652
    while ((j=AH_Job_List_First(jl))) {
653
      DBG_INFO(AQHBCI_LOGDOMAIN, "Moving job \"%s\" from todo queue to finished jobs", AH_Job_GetName(j));
654
      AH_Job_List_Del(j);
655
      AH_Job_List_Add(j, finishedJobs);
656
    } /* while */
657
    AH_Job_List_free(jl);
658
    AH_JobQueue_free(jq);
659
  } /* while */
660

    
661
  if (AH_Job_List_GetCount(todoJobs)) {
662
    AH_JOB *j;
663

    
664
    while ((j=AH_Job_List_First(todoJobs))) {
665
      DBG_INFO(AQHBCI_LOGDOMAIN, "Moving job \"%s\" from todo queue to finished jobs",
666
               AH_Job_GetName(j));
667
      AH_Job_List_Del(j);
668
      AH_Job_List_Add(j, finishedJobs);
669
    } /* while */
670
  }
671
}
672

    
673

    
674