Subversion Repositories HelenOS

Rev

Rev 2873 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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