Logo Search packages:      
Sourcecode: blender version File versions  Download package

v_func_storage.c

/*
 * 
*/

#include <stdio.h>
#include <stdlib.h>
#include "verse_header.h"
#include "v_pack.h"
#include "v_cmd_gen.h"
#include "v_connection.h"
#if !defined(V_GENERATE_FUNC_MODE)
#include "verse.h"
#include "v_cmd_buf.h"
#include "v_network_out_que.h"

#define V_FS_MAX_CMDS   256

extern void init_pack_and_unpack(void);

static struct {
      unsigned int      (*unpack_func[V_FS_MAX_CMDS])(const char *data, size_t length);
      void        *pack_func[V_FS_MAX_CMDS];
      void        *user_func[V_FS_MAX_CMDS];
      void        *user_data[V_FS_MAX_CMDS];
      void        *alias_pack_func[V_FS_MAX_CMDS];
      void        *alias_user_func[V_FS_MAX_CMDS];
      void        *alias_user_data[V_FS_MAX_CMDS];
      boolean           call;
} VCmdData;

static boolean v_fs_initialized = FALSE;

extern void verse_send_packet_ack(uint32 packet_id);
extern void callback_send_packet_ack(void *user, uint32 packet_id);
extern void verse_send_packet_nak(uint32 packet_id);
extern void callback_send_packet_nak(void *user, uint32 packet_id);

void v_fs_init(void)
{
      unsigned int i;
      if(v_fs_initialized)
            return;
      for(i = 0; i < V_FS_MAX_CMDS; i++)
      {
            VCmdData.unpack_func[i] = NULL;
            VCmdData.pack_func[i] = NULL;
            VCmdData.user_func[i] = NULL;
            VCmdData.user_data[i] = NULL;
            VCmdData.alias_pack_func[i] = NULL;
            VCmdData.alias_user_func[i] = NULL;
            VCmdData.alias_user_data[i] = NULL;
      }
      #if !defined(V_GENERATE_FUNC_MODE)
      init_pack_and_unpack();
      #endif
      for(i = 0; i < V_FS_MAX_CMDS && VCmdData.pack_func[i] != verse_send_packet_ack; i++);
      VCmdData.user_func[i] = callback_send_packet_ack;
      for(i = 0; i < V_FS_MAX_CMDS && VCmdData.pack_func[i] != verse_send_packet_nak; i++);
      VCmdData.user_func[i] = callback_send_packet_nak;

      v_fs_initialized = TRUE;
}


void v_fs_add_func(unsigned int cmd_id, unsigned int (*unpack_func)(const char *data, size_t length), void *pack_func, void *alias_func)
{
      VCmdData.unpack_func[cmd_id] = unpack_func;
      VCmdData.pack_func[cmd_id] = pack_func;
      VCmdData.alias_pack_func[cmd_id] = alias_func;
}

void *v_fs_get_user_func(unsigned int cmd_id)
{
/*    if(VCmdData.call)*/
            return VCmdData.user_func[cmd_id];
      return NULL;
}

void *v_fs_get_user_data(unsigned int cmd_id)
{
      return VCmdData.user_data[cmd_id];
}

void *v_fs_get_alias_user_func(unsigned int cmd_id)
{
/*    if(VCmdData.call)*/
            return VCmdData.alias_user_func[cmd_id];
      return NULL;
}

void *v_fs_get_alias_user_data(unsigned int cmd_id)
{
      return VCmdData.alias_user_data[cmd_id];
}

void verse_callback_set(void *command, void *callback, void *user)
{
      unsigned int i;
      if(!v_fs_initialized)
            v_fs_init();

      for(i = 0; i < V_FS_MAX_CMDS; i++)
      {
            if(VCmdData.pack_func[i] == command)
            {
                  VCmdData.user_data[i] = user;
                  VCmdData.user_func[i] = callback;
                  return;
            }
            if(VCmdData.alias_pack_func[i] == command)
            {
                  VCmdData.alias_user_data[i] = user;
                  VCmdData.alias_user_func[i] = callback;
                  return;
            }
      }
}

/* Do we accept incoming connections, i.e. are we a host implementation? */
boolean v_fs_func_accept_connections(void)
{
      return VCmdData.user_func[0] != NULL;
}

/* Inspect beginning of packet, looking for ACK or NAK commands. */
void v_fs_unpack_beginning(const uint8 *data, unsigned int length)
{
      uint32 id, i = 4;
      uint8 cmd_id;

      i += vnp_raw_unpack_uint8(&data[i], &cmd_id);
      while(i < length && (cmd_id == 7 || cmd_id == 8))
      {
            i += vnp_raw_unpack_uint32(&data[i], &id);
            if(cmd_id == 7)
                  callback_send_packet_ack(NULL, id);
            else
                  callback_send_packet_nak(NULL, id);
            i += vnp_raw_unpack_uint8(&data[i], &cmd_id);
      }
}

void v_fs_unpack(uint8 *data, unsigned int length)
{
      uint32 i, output, pack_id;
      uint8 cmd_id, last = 255;

      i = vnp_raw_unpack_uint32(data, &pack_id); /* each packet starts with a 32 bit id */
      vnp_raw_unpack_uint8(&data[i], &cmd_id);
      while(i < length && (cmd_id == 7 || cmd_id == 8))
      {
            i += 5;
            vnp_raw_unpack_uint8(&data[i], &cmd_id);
      }
      while(i < length)
      {
            i += vnp_raw_unpack_uint8(&data[i], &cmd_id);
            if(VCmdData.unpack_func[cmd_id] != NULL)
            {
                  VCmdData.call = TRUE;
                  output = VCmdData.unpack_func[cmd_id](&data[i], length - i);
                  if(output == (unsigned int) -1)     /* Can this happen? Should be size_t or int, depending. */
                  {
                        printf("** Aborting decode, command %u unpacker returned failure\n", cmd_id);
/*                      verse_send_packet_nak(pack_id);*/
                        return;
                  }
                  last = cmd_id;
                  i += output;
            }
            else  /* If unknown command byte was found, complain loudly and stop parsing packet. */
            {
                  size_t      j;

                  printf("\n** Unknown command ID %u (0x%02X) encountered--aborting packet decode len=%u pos=%u last=%u\n", cmd_id, cmd_id, length, i, last);
                  printf(" decoded %u bytes: ", --i);
                  for(j = 0; j < i; j++)
                        printf("%02X ", data[j]);
                  printf("\n (packet id=%u)", pack_id);
                  printf(" remaining %u bytes: ", length - i);
                  for(j = i; j < length; j++)
                        printf("%02X ", data[j]);
                  printf("\n");
/*                *(char *) 0 = 0;*/
                  break;
            }
      }
/*    if(expected != NULL)
            verse_send_packet_ack(pack_id);*/
}

extern unsigned int v_unpack_connection(const char *data, size_t length);

#endif

Generated by  Doxygen 1.6.0   Back to index