Subversion Repositories HelenOS

Rev

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

  1. /** @addtogroup sctrace
  2.  * @{
  3.  */
  4. /** @file
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <libadt/hash_table.h>
  10.  
  11. #include "ipc_desc.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;
  22.  
  23. typedef struct {
  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[])
  36. {
  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. {
  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.  
  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.  
  105. void ipcp_call_out(int phone, ipc_call_t *call, ipc_callid_t hash)
  106. {
  107.     pending_call_t *pcall;
  108.  
  109. //  printf("ipcp_call_out()\n");
  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",
  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.     );
  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);
  128. }
  129.  
  130. void ipcp_call_in(ipc_call_t *call, ipc_callid_t hash)
  131. {
  132.     link_t *item;
  133.     pending_call_t *pcall;
  134.  
  135. //  printf("ipcp_call_in()\n");
  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",
  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)
  144.     );*/
  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);
  161. }
  162.  
  163. void ipcp_call_sync(int phone, ipc_call_t *call, ipc_call_t *answer)
  164. {
  165.     ipcp_call_out(phone, call, 0);
  166.     ipcp_call_in(answer, 0);
  167. }
  168.  
  169. void ipcp_hangup(int phone, int rc)
  170. {
  171.     printf("hangup phone %d -> %d\n", phone, rc);
  172. }
  173.  
  174. /** @}
  175.  */
  176.