Subversion Repositories HelenOS

Rev

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