Initial revision
[silc.git] / lib / silccore / silcprotocol.c
1 /*
2
3   silcprotocol.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * Created: Tue Nov 25 19:25:33 GMT+0200 1997
22  */
23 /*
24  * $Id$
25  * $Log$
26  * Revision 1.1  2000/06/27 11:36:55  priikone
27  * Initial revision
28  *
29  *
30  */
31
32 #include "silcincludes.h"
33 #include "silcprotocol.h"
34
35 /* Allocates a new protocol object. The new allocated and initialized 
36    protocol is returned to the new_protocol argument. The argument context
37    is the context to be sent as argument for the protocol. The callback
38    argument is the function to be called _after_ the protocol has finished. */
39
40 void silc_protocol_alloc(SilcProtocolType type, SilcProtocol *new_protocol,
41                          void *context, SilcProtocolFinalCallback callback)
42 {
43   int i;
44
45   SILC_LOG_DEBUG(("Allocating new protocol type %d", type));
46
47   for (i = 0; silc_protocol_list[i].callback; i++)
48     if (silc_protocol_list[i].type == type)
49       break;
50
51   if (!silc_protocol_list[i].callback) {
52     SILC_LOG_ERROR(("Requested protocol does not exists"));
53     return;
54   }
55
56   *new_protocol = silc_calloc(1, sizeof(**new_protocol));
57   if (*new_protocol == NULL) {
58     SILC_LOG_ERROR(("Cannot allocate new protocol object"));
59     return;
60   }
61
62   (*new_protocol)->protocol = (SilcProtocolObject *)&silc_protocol_list[i];
63   (*new_protocol)->state = SILC_PROTOCOL_STATE_UNKNOWN;
64   (*new_protocol)->context = context;
65   (*new_protocol)->execute = silc_protocol_execute;
66   (*new_protocol)->execute_final = silc_protocol_execute_final;
67   (*new_protocol)->final_callback = callback;
68 }
69
70 /* Free's a protocol object. */
71
72 void silc_protocol_free(SilcProtocol protocol)
73 {
74   if (protocol)
75     silc_free(protocol);
76 }
77
78 /* Executes next state of the protocol. The state must be set before
79    calling this function. */
80
81 void silc_protocol_execute(void *qptr, int type,
82                            void *context, int fd,
83                            long secs, long usecs)
84 {
85   SilcProtocol protocol = (SilcProtocol)context;
86
87   SILC_LOG_DEBUG(("Start"));
88
89   if (secs + usecs) 
90     silc_task_register(qptr, fd, protocol->protocol->callback, context, 
91                        secs, usecs, 
92                        SILC_TASK_TIMEOUT,
93                        SILC_TASK_PRI_NORMAL);
94   else
95     protocol->protocol->callback(qptr, 0, context, fd);
96 }
97
98 /* Executes the final callback of the protocol. */
99
100 void silc_protocol_execute_final(void *qptr, int type,
101                                  void *context, int fd)
102 {
103   SilcProtocol protocol = (SilcProtocol)context;
104  
105   SILC_LOG_DEBUG(("Start, state=%d", protocol->state));
106
107   protocol->final_callback(qptr, 0, context, fd);
108 }