Subversion Repositories HelenOS

Rev

Rev 2872 | Rev 2874 | 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 "ipc.h"
  13.  
  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[])
  27. {
  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. {
  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.  
  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.  
  96. void ipc_parse_call_out(int phone, ipc_call_t *call, ipc_callid_t hash)
  97. {
  98.     pending_call_t *pcall;
  99.  
  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",
  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.     );
  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);
  119. }
  120.  
  121. void ipc_parse_call_in(ipc_call_t *call, ipc_callid_t hash)
  122. {
  123.     link_t *item;
  124.     pending_call_t *pcall;
  125.  
  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",
  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)
  135.     );*/
  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);
  152. }
  153.  
  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. }
  159.  
  160. void ipc_parse_hangup(int phone, int rc)
  161. {
  162.     printf("hangup phone %d -> %d\n", phone, rc);
  163. }
  164.  
  165. /** @}
  166.  */
  167.