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 |