Subversion Repositories HelenOS

Rev

Rev 2873 | Rev 2877 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2871 svoboda 1
/** @addtogroup sctrace
2
 * @{
3
 */
4
/** @file
5
 */
6
 
7
#include <stdio.h>
2873 svoboda 8
#include <stdlib.h>
9
#include <libadt/hash_table.h>
2871 svoboda 10
 
11
#include "ipc_desc.h"
2874 svoboda 12
#include "ipcp.h"
2871 svoboda 13
 
2873 svoboda 14
typedef struct {
2874 svoboda 15
    int phone_hash;
16
    ipc_call_t question;
17
 
18
    int call_hash;
19
 
20
    link_t link;
21
} pending_call_t;
22
 
23
typedef struct {
2873 svoboda 24
    int server;
25
    proto_t *proto;
26
} connection_t;
27
 
28
#define MAX_PHONE 64
29
connection_t connections[MAX_PHONE];
30
int have_conn[MAX_PHONE];
31
 
32
#define PCALL_TABLE_CHAINS 32
33
hash_table_t pending_calls;
34
 
35
hash_index_t pending_call_hash(unsigned long key[])
2871 svoboda 36
{
2873 svoboda 37
    printf("pending_call_hash\n");
38
    return key[0] % PCALL_TABLE_CHAINS;
39
}
40
 
41
int pending_call_compare(unsigned long key[], hash_count_t keys, link_t *item)
42
{
43
    pending_call_t *hs;
44
 
45
    printf("pending_call_remove_compare\n");
46
    hs = hash_table_get_instance(item, pending_call_t, link);
47
 
48
    return key[0] == hs->call_hash;
49
}
50
 
51
void pending_call_remove_callback(link_t *item)
52
{
53
    printf("pending_call_remove_callback\n");
54
}
55
 
56
hash_table_operations_t pending_call_ops = {
57
    .hash = pending_call_hash,
58
    .compare = pending_call_compare,
59
    .remove_callback = pending_call_remove_callback
60
};
61
 
62
static void connection_set(int phone, int server, proto_t *proto)
63
{
64
    if (phone <0 || phone >= MAX_PHONE) return;
65
    connections[phone].server = server;
66
    connections[phone].proto = proto;
67
    have_conn[phone] = 1;
68
}
69
 
70
static void connection_clear(int phone)
71
{
72
    have_conn[phone] = 0;
73
    connections[phone].server = 0;
74
    connections[phone].proto = NULL;
75
}
76
 
77
static void ipc_m_print(ipcarg_t method)
78
{
2872 svoboda 79
    ipc_m_desc_t *desc;
80
 
81
    /* FIXME: too slow */
82
    desc = ipc_methods;
83
    while (desc->number != 0) {
84
        if (desc->number == method) {
85
            printf("%s (%d)", desc->name, method);
86
            return;
87
        }
88
 
89
        ++desc;
90
    }
91
 
92
    printf("%d", method);
93
}
94
 
2873 svoboda 95
void ipcp_init(void)
96
{
97
    hash_table_create(&pending_calls, PCALL_TABLE_CHAINS, 1, &pending_call_ops);
98
}
99
 
100
void ipcp_cleanup(void)
101
{
102
    hash_table_destroy(&pending_calls);
103
}
104
 
2874 svoboda 105
void ipcp_call_out(int phone, ipc_call_t *call, ipc_callid_t hash)
2872 svoboda 106
{
2873 svoboda 107
    pending_call_t *pcall;
108
 
2874 svoboda 109
//  printf("ipcp_call_out()\n");
2872 svoboda 110
    printf("call id: 0x%x, phone: %d, method: ", hash, phone);
111
    ipc_m_print(IPC_GET_METHOD(*call));
112
    printf(" args: (%u, %u, %u, %u, %u)\n",
2871 svoboda 113
        IPC_GET_ARG1(*call),
114
        IPC_GET_ARG2(*call),
115
        IPC_GET_ARG3(*call),
116
        IPC_GET_ARG4(*call),
117
        IPC_GET_ARG5(*call)
118
    );
2873 svoboda 119
 
120
    /* Store call in hash table for response matching */
121
 
122
    pcall = malloc(sizeof(pending_call_t));
123
    pcall->phone_hash = phone;
124
    pcall->question = *call;
125
    pcall->call_hash = hash;
126
 
127
    hash_table_insert(&pending_calls, &pcall->call_hash, &pcall->link);
2871 svoboda 128
}
129
 
2874 svoboda 130
void ipcp_call_in(ipc_call_t *call, ipc_callid_t hash)
2871 svoboda 131
{
2873 svoboda 132
    link_t *item;
133
    pending_call_t *pcall;
134
 
2874 svoboda 135
//  printf("ipcp_call_in()\n");
2872 svoboda 136
/*  printf("phone: %d, method: ", call->in_phone_hash);
137
    ipc_m_print(IPC_GET_METHOD(*call));
138
    printf(" args: (%u, %u, %u, %u, %u)\n",
2871 svoboda 139
        IPC_GET_ARG1(*call),
140
        IPC_GET_ARG2(*call),
141
        IPC_GET_ARG3(*call),
142
        IPC_GET_ARG4(*call),
143
        IPC_GET_ARG5(*call)
2872 svoboda 144
    );*/
2873 svoboda 145
 
146
    if ((hash & IPC_CALLID_ANSWERED) == 0) {
147
        /* Not a response */
148
        printf("Not a response\n");
149
        return;
150
    }
151
 
152
    hash = hash & ~IPC_CALLID_ANSWERED;
153
 
154
    item = hash_table_find(&pending_calls, &hash);
155
    if (item == NULL) return; // No matching question found
156
 
157
    pcall = hash_table_get_instance(item, pending_call_t, link);
158
 
159
    printf("response matched to question\n");
160
    hash_table_remove(&pending_calls, &hash, 1);
2871 svoboda 161
}
162
 
2874 svoboda 163
void ipcp_call_sync(int phone, ipc_call_t *call, ipc_call_t *answer)
2872 svoboda 164
{
2874 svoboda 165
    ipcp_call_out(phone, call, 0);
166
    ipcp_call_in(answer, 0);
2872 svoboda 167
}
2871 svoboda 168
 
2874 svoboda 169
void ipcp_hangup(int phone, int rc)
2872 svoboda 170
{
171
    printf("hangup phone %d -> %d\n", phone, rc);
172
}
173
 
2871 svoboda 174
/** @}
175
 */