#include <stdio.h>
#include <malloc.h>
#include </usr/local/include/libraw1394/csr.h>
#include </usr/local/include/libraw1394/raw1394.h>
#include "uc1394.h"

#define DEBUG 1 // Debug status
#define PORT  0 // Port to be used on 1394 card

#define KERNEL_BUFFER 8192 // redefine the kernel buffer for two iso reads or 2*max_packet_size

// Locally used definitions
//      handlers
raw1394handle_t handle;
bus_reset_handler_t old_reset_handler;
//      node of the uc1394
int node = -1;
//      return data from read
quadlet_t buffer;
//      buffer for iso reads and transmit
unsigned int *data;
unsigned int data_length;
unsigned long int data_index;
//      register offset
quadlet_t Csr_Register_Base;
//      amount of data sent reveived
unsigned int long total;
//      iso stream direction
unsigned int long iso_dir;
//      iso byte order
unsigned int byte_order;
//      iso max packet size
unsigned int max_packet_size;
//      iso ack interface
struct interface iso_ack;

unsigned int iso_channel;

// private funtion prototypes
// handlers
enum raw1394_iso_disposition my_iso_transmit_handler(raw1394handle_t, unsigned char *, unsigned int *, unsigned char *, unsigned char *, int, unsigned int);
enum raw1394_iso_disposition my_iso_receive_handler(raw1394handle_t, unsigned char *, unsigned int, unsigned char, unsigned char, unsigned char, unsigned int, unsigned int);

int my_iso_handler(raw1394handle_t, int, size_t, quadlet_t *);

int my_bus_reset_handler(raw1394handle_t, unsigned int);

// helper functions
int set_up_parameters(struct interface *);
int set_csr_register_offset(void);
struct parameter read_parameter(unsigned long int);
unsigned long int get_parameter(struct interface, unsigned long int);
unsigned long int search_registers(unsigned int, unsigned int, unsigned long int, int, unsigned long int);
quadlet_t byte_swap(quadlet_t);

// Public function calls **************************************************************************************

int UC1394_init() // set up the node for the UC1394 then find the CSR offset
{
  int i;
  struct raw1394_portinfo pinf[16];
  handle = raw1394_new_handle();
  node = -1;
  
  
  if(!handle){
    if(DEBUG)
      printf("Could not get handle\n");
    exit(1);
  }
  
  raw1394_get_port_info(handle, pinf, 16);
   
  if(raw1394_set_port(handle, PORT) < 0)
    exit(1);

  if(pinf[PORT].nodes == 1){
    if(DEBUG)
      printf("No devices connected to this firewire port, please connect the uc1394 and try again\n");
    exit(0);
  }

  // Search the nodes to find the uc1394
  // loop breaks when found
  for (i = 0; i < pinf[PORT].nodes; i++) {
    if(DEBUG)
      printf("Checking node %d\n", i);

    buffer = 0;

    if (raw1394_start_read(handle, 0xffc0 | i, UCBASE+UC_BUS_BASE+0x0008, 4, &buffer, 0) < 0)
      if(DEBUG)
	printf("failed to read the node\n");
    raw1394_loop_iterate(handle);
   
    // check the last value and see if its the uc1394
    if((byte_swap(buffer)&0xFFFFFF00)>>8 == 0xB02A){
      node = i;
      break;
    }

  }

  // check the last value and make sure its the uc1394
  // good check if the loop exits without finding the uc1394
  if((byte_swap(buffer)&0xFFFFFF00)>>8 != 0xB02A){
    printf("Failed to find the uc1394\n");
    exit(0);
  }

  if(DEBUG)
    printf("Found UC1394 at node %d\n", node);
  
  // set and return 1 if the csr offset if set or 0 if not
  if(!set_csr_register_offset())
    return 0;

  // ************************************************************************************
  //  old_reset_handler = raw1394_set_bus_reset_handler(handle, my_bus_reset_handler);
  //  if(raw1394_busreset_notify(handle, RAW1394_NOTIFY_ON) < 0)
  //     if(DEBUG)
  //       printf("Could not turn on the bus reset notifier\n");
  // ************************************************************************************
  
  return 1;
}

struct interface UC1394_get_interface(unsigned long int type, unsigned long int instance) // get interfaces for the user
{
  struct interface x;
  quadlet_t temp;
  unsigned long int csr_offset = 0x0004;
  unsigned char found = 0;

  if(DEBUG)
    printf("Getting interface\n");
  
  x.interface_type = NOT_FOUND; // Defualt interface is not found
  
  // return a null interface if csr offset has not be initialized
  if(Csr_Register_Base == 0x0){
    printf("CSR_BASE = 0x0\n");
    return x;
  }

  //  printf("Entering while loop 0x%X\n", Csr_Register_Base);

  // loop until found or error occurs
  while(!found){
    // check to see if the device is readable
    if (raw1394_start_read(handle, 0xffc0 | node, UCBASE + Csr_Register_Base + csr_offset, 4, &buffer, 0) < 0) {
      printf("Could not read device\n");
      x.interface_type = NOT_FOUND;
      return x;
    }
    raw1394_loop_iterate(handle);
    
    // store the type of interface for later use
    temp = byte_swap(buffer);
    
    // if the interface is the right type then gather the other information
    // assuming its a type 0 interface with minimal inforamtion
    if((temp&0xFFFF0000)>>16 == type) {
      
      if(DEBUG)
	printf("Found the type\n");
      
      if (raw1394_start_read(handle, 0xffc0 | node, UCBASE + Csr_Register_Base + csr_offset + 0x0004, 4, &buffer, 0) < 0) {
	printf("Could not read device\n");
	x.interface_type = NOT_FOUND;
	return x;
      }
      raw1394_loop_iterate(handle);
      
      if(DEBUG)
	printf("Checking instance 0x%X\n", byte_swap(buffer));
      
      // check to see if the instances matches (mainly for the io pin interfaces)
      if(byte_swap(buffer) == instance){
	
	if(DEBUG)
	  printf("Found the interface\n");
	
	// set the instance and type
	x.interface_type = type;
	x.interface_instance = instance;

	if (raw1394_start_read(handle, 0xffc0 | node, UCBASE + Csr_Register_Base + csr_offset + 0x0008, 4, &buffer, 0) < 0) {
	  printf("Could not read device\n");
	  x.interface_type = NOT_FOUND;
	  return x;
	}
	raw1394_loop_iterate(handle);
	
	if(DEBUG)
	  printf("Found the parameter offset\n");
	
	// set the parameter offset
	x.parameter_offset = (byte_swap(buffer)*0x0004);

	if (raw1394_start_read(handle, 0xffc0 | node, UCBASE + Csr_Register_Base + csr_offset + 0x000C, 4, &buffer, 0) < 0) {
	  printf("Could not read device\n");
	  x.interface_type = NOT_FOUND;
	  return x;
	}
	raw1394_loop_iterate(handle);

	if(DEBUG)
	  printf("Found the software reg offset\n");
	
	// set the software register offset
	x.software_reg_offset = (byte_swap(buffer)*0x0004);

	if (raw1394_start_read(handle, 0xffc0 | node, UCBASE + Csr_Register_Base + csr_offset + 0x0010, 4, &buffer, 0) < 0) {
	  printf("Could not read device\n");
	  x.interface_type = NOT_FOUND;
	  return x;
	}
	raw1394_loop_iterate(handle);

	// set the software register size
	x.software_reg_size = byte_swap(buffer);
	
	// gathered all the information for this instance
	found = 1;
	
	if(DEBUG){
	  printf("Found the interface at register 0x%X\n", Csr_Register_Base + csr_offset); 
	  printf("Interface type: 0x%8X\n", x.interface_type);
	  printf("Interface parameter offset: 0x%8X\n", x.parameter_offset);
	  printf("Interface software offset: 0x%8X\n", x.software_reg_offset);
	}

	 // init parameters here
	 if(!set_up_parameters(&x)) {
	   // if cannot initialize the software registers set the interface to null and return
	   x.interface_type = NOT_FOUND;
	   if(DEBUG)
	     printf("Could not init software registers\n");
	 }
	 
	 // return the interface after it's been found
	 return x;
       }
     }

    // didn't find the interface yet so goto the next interface
     csr_offset += ((temp&0x0000FFFF)*0x0004);
     
     // check to make sure that there will be a next interface
     if((temp&0x0000FFFF) == 0){
       x.interface_type = NOT_FOUND;
       found = 0;
       break;
     }
  }

  // return the null interface if at the end of the csr register and still have not found the specified interface
  return x;
}

int UC1394_set_IO_PIN_state(struct interface inst, unsigned long int value) // changes the io pin state
{
  // set up the buffer to send to the software register
  buffer = ((value&0x01)<<24) | 
           ((get_parameter(inst, IO_PARTNER_DEV)&0x3F)<<16) | 
           ((get_parameter(inst, IO_PARTNER_INST)&0xFF)<<8) | 
           0x00;
  // return 1 on good write, 0 on failure
  if(raw1394_start_write(handle, 0xffc0 | node, UCBASE+Csr_Register_Base+inst.software_reg_offset, 4, &buffer, 0) < 0)
      return 0;    
  return 1;
}

int UC1394_init_STREAMING(struct interface inst, unsigned long int dir) // set up the iso handlers depending on the stream direction
{
  total = 0;
  iso_ack.interface_type = NOT_FOUND;
  
  if(inst.interface_type != STREAMING_PORT)
    return 0;
  
  if(DEBUG)
    printf("Streaming clock in mode 0x%X\n", get_parameter(inst, STR_CLKM));

  // might make this user changable
  iso_channel = get_parameter(inst, STR_ID); 

  if(DEBUG)
    printf("Channel as defined by the UC1394 %d\n", iso_channel);

  byte_order = get_parameter(inst, STR_ENDIAN);
  if(DEBUG)
    printf("Endainess is %d\n", byte_order);

  // set the payload for the iso channel
  max_packet_size = get_parameter(inst, STR_PKTSIZE);
  if(DEBUG)
    printf("For 1.8 should be 64, for .9 should be 2400 current = %d\n", max_packet_size);
  
  // set the global varable used in UC1394_start_STREAMING
  iso_dir = dir;

  if(iso_dir == STREAMING_RECV) {
    if(raw1394_set_iso_handler(handle, iso_channel, my_iso_handler) < 0) {
      printf("Failed to set the iso handler\n");
      raw1394_stop_iso_rcv(handle, iso_channel);
      raw1394_set_iso_handler(handle, iso_channel, NULL);
      return 0;
    }
    return 1;
  }

  if(iso_dir == STREAMING_TRANS) {
    if(raw1394_iso_xmit_init(handle, my_iso_transmit_handler, (max_packet_size*2), max_packet_size, iso_channel, RAW1394_ISO_SPEED_400, -1) <0){
      printf("Could not set the iso tran handler on channel %c\n", iso_channel);
      return 0;
    }
    return 1;
  }
  
  // if both inits failed then return 0
  return 0;
}

int UC1394_start_STREAMING(struct interface inst, unsigned int *d, unsigned long int size) // starts collecting the data 
// as well as pre allocating memory  takes control of the computer for the entire transfer !!!!!!!!!!!!!!!!!!!!!
{
  //  malloc memory here for data!!!
  if(!d) {
    if(DEBUG)
      printf("Mallocing memory for streaming data\n");
    d = (unsigned int *)malloc(size * sizeof(unsigned int));
    memset(d, 0, size);
  }

  total = 0;
  data = d;
  data_index = 0;
  data_length = size;

  // start the iso recv handler
  if(iso_dir == STREAMING_RECV) {
    if(raw1394_start_iso_rcv(handle, 0) < 0) {
       printf("Could not set the iso handler\n");
      return 0;
    }
  }
    

  // enable the streaming port on the uc1394 device
  //  buffer = ((STREAMING_ENABLE&0x01)<<24) | 
  //    ((get_parameter(inst, STR_DIR)&0x01)<<25) | 
  //    ((get_parameter(inst, STR_PARTNER_DEV)&0x3F)<<16) | 
  //    ((get_parameter(inst, STR_PARTNER_INST)&0xFF)<<8) | 
  //    0x00;

  // write the command to enable the streaming port to the software register on the uc1394
  //  if(raw1394_start_write(handle, 0xffc0 | node, UCBASE+Csr_Register_Base+inst.software_reg_offset, 4, &buffer, 0) < 0)
  //    return 0;

  // if transmitting start transmitting
  if(iso_dir == STREAMING_TRANS)
    raw1394_iso_xmit_start(handle, -1, -1);

  //  loop until all done to drive packet processing
  while(total != size) {
    printf("Collected %d bytes\n", total);

    //  UC1394_set_IO_PIN_state(iso_ack, IO_PIN_OFF);
    
    raw1394_loop_iterate(handle);
      
  //    UC1394_set_IO_PIN_state(iso_ack, IO_PIN_ON);
  }
  
  return 1;
}

int UC1394_stop_STREAMING(struct interface inst)  // stops the streaming interface
{
  // command to stop the uc1394 streaming port
  buffer = ((STREAMING_DISABLE&0x01)<<24) | 
    ((get_parameter(inst, STR_DIR)&0x01)<<25) | 
    ((get_parameter(inst, STR_PARTNER_DEV)&0x3F)<<16) | 
    ((get_parameter(inst, STR_PARTNER_INST)&0xFF)<<8) | 
    0x00;
  
  // write the command to the uc1394 software register
  if(raw1394_start_write(handle, 0xffc0 | node, UCBASE+Csr_Register_Base+inst.software_reg_offset, 4, &buffer, 0) < 0)
    return 0;
  total = 0;
  
  if(iso_dir == STREAMING_RECV)
    raw1394_stop_iso_rcv(handle, iso_channel);

  // stop the iso handlers
  // raw1394_iso_stop(handle);
  
  return total; // return the total collected / send blocks of data

}

int UC1394_set_STREAMING_ACK(struct interface inst)
{
  iso_ack = inst;
  return 1;
}

int UC1394_close() // close the device
{
  if(node != -1) {
    raw1394_iso_shutdown(handle);
    // ******************************************************************
    // raw1394_set_bus_reset_handler(handle, old_reset_handler);
    // ******************************************************************
    raw1394_destroy_handle(handle);
    node = -1;
  }
  return 1;
}

// Private function calls **********************************************************************************************

int set_csr_register_offset() // set the csr register offset used to get the interfaces
{
  // init the unit dir to zero
  unsigned long int unit_dir = 0x0;

  if(DEBUG){
    printf("Looking for the sotware registers\n");
    printf("Reading root dir\n");
  }

  // read the first entry in the root dir and find the length of the dir structure
  if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+UC_ROOT_BASE, 4, &buffer, 0) < 0)
    return 0;
  raw1394_loop_iterate(handle);

  if(DEBUG)
    printf("Going from register 0x%12LX to 0x%12LX\n", UCBASE+UC_ROOT_BASE, UCBASE+UC_ROOT_BASE+(((byte_swap(buffer)&0xFFFF0000)>>16)*0x0004));
  
  // search in the root dir for the unit dir offset
  unit_dir = search_registers(UC_ROOT_BASE, UC_ROOT_BASE+(((byte_swap(buffer)&0xFFFF0000)>>16)*0x0004), ENTRY_TYPE_MASK, ENTRY_MASK_SHIFT_SIZE, UNIT_DIRECTORY_OFFSET);

  // if the unit dir is not found return 0
  if(unit_dir == 0x0)
    return 0;
  
  if(DEBUG)
    printf("Reading unit dir\n");

  // read the first entry in the root dir and find the length of the dir structure
  if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+unit_dir, 4, &buffer, 0) < 0)
    return 0;
  raw1394_loop_iterate(handle);
  
  if(DEBUG)
    printf("Going from register 0x%12LX to 0x%12LX\n", UCBASE + unit_dir, UCBASE + unit_dir+(((byte_swap(buffer)&0xFFFF0000)>>16)*0x0004));
  
  // search in the unit dir for the csr offset
  search_registers(unit_dir, unit_dir+(((byte_swap(buffer)&0xFFFF0000)>>16)*0x0004), ENTRY_TYPE_MASK, ENTRY_MASK_SHIFT_SIZE, CSR_OFFSET); 
  Csr_Register_Base = (byte_swap(buffer)&0x00FFFFFF)*0x0004;
  if(Csr_Register_Base == 0x0)
    return 0;
  
  if(DEBUG){
    printf("Found the csr offset register at 0x%X\n", Csr_Register_Base);
    printf("Checking magic number\n");
  }

  // check the csr offset with the magic number 
  if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+Csr_Register_Base, 4, &buffer, 0) < 0)
    return 0;
  raw1394_loop_iterate(handle);
  
  if(byte_swap(buffer) != UC_MAGIC_NUMBER)
    exit(1);
  
  if(DEBUG)
    printf("Set CSR Base\n");
  
  return 1;

}

int set_up_parameters(struct interface *inst)  // used to map out the parameter structure for a given interface
{
  int i = 0;
  unsigned long int reg_offset = inst->parameter_offset;
  struct parameter current;
  
  if(DEBUG)
    printf("Trying to read the interface parameters\n");
  
  do{  
    current = read_parameter(reg_offset);
    inst->parameters[i] = current;

    if(DEBUG){
      printf("Current parameter info\n");
      printf("current_offset  = 0x%8X\n", reg_offset);
      printf("next_descriptor = 0x%8X\n", current.next_descriptor);
      printf("parameter_id    = 0x%8X\n", current.parameter_id);
      printf("parameter_flags = 0x%8X\n", current.parameter_flags);
      printf("current_value   = 0x%8X\n", current.current_value);
    }

    reg_offset += (current.next_descriptor*0x0004);
    i++;
    if(i >= MAX_PARAMETER_LENGTH)
      return 0;
  }while (current.next_descriptor != 0x0000);

  return 1;
}

unsigned long int get_parameter(struct interface inst, unsigned long int par) // used to return the specified parameters value
{
  int i;
  // Check to make sure that the parameter is within the range of the given interface type
  switch(inst.interface_type){
  case DEVICE:
    if(par < DEV_ID || par > FPGA_REVISION)
      return 0;
    break;
  case STREAMING_PORT:
    if(par < STR_ID || par >  STR_PARTNER_INST)
      return 0;
    break;
  case IO_PIN:
    if(par < IO_DIR || par > IO_PARTNER_INST)
      return 0;
    break;
  case UART:
    if(par <  UART_BAUD || par > UART_PARTNER_INST)
      return 0;
    break;
  defualt:
    return 0;
    break;
  }

  // Parse the interface for the paramter and return the current value
  for(i = 0; i < MAX_PARAMETER_LENGTH; i++){
    if((inst.parameters[i]).parameter_id == par)
      return (inst.parameters[i]).current_value;
  }
  return 0;
}

struct parameter read_parameter(unsigned long int offset)  // initializes a parameter specified by the offset
{                                                          // assumes the parameter is of type zero
                                                           // parameters are loaded on boot of the uc1394 and do not change
  struct parameter current_parameter;
 
  if(DEBUG)
    printf("Reading parameter\n");

  if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+Csr_Register_Base+offset+0x0000, 4, &buffer, 0) < 0)
    return current_parameter;
  raw1394_loop_iterate(handle);

  if(DEBUG)
    printf("Next desc 0x%X\n", (byte_swap(buffer)&0x0000FFFF));
  
  // set the next descripter offset
  current_parameter.next_descriptor = (byte_swap(buffer)&0x0000FFFF);

  if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+Csr_Register_Base+offset+0x0004, 4, &buffer, 0) < 0)
    return current_parameter;
  raw1394_loop_iterate(handle);

  if(DEBUG)
    printf("Param id 0x%X\n", ((byte_swap(buffer)&0xFFFF0000)>>16));

  // set the parameter id
  current_parameter.parameter_id = ((byte_swap(buffer)&0xFFFF0000)>>16);
  
  if(DEBUG)
    printf("Param Flags 0x%X\n", (byte_swap(buffer)&0x0000FFFF));

  // sets the parameter flags
  current_parameter.parameter_flags = (byte_swap(buffer)&0x0000FFFF);

  if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+Csr_Register_Base+offset+0x0008, 4, &buffer, 0) < 0)
    return current_parameter;
  raw1394_loop_iterate(handle);
  
  if(DEBUG)
    printf("Current value 0x%X\n", byte_swap(buffer));

  // set the current value of the parameter
  current_parameter.current_value = byte_swap(buffer);
  
  return current_parameter;
}

unsigned long int search_registers(unsigned int beg, unsigned int end, unsigned long int mask, int mask_shift, unsigned long int cond)
{                                  // search in given region for the condition and return the offset for type of entry
  unsigned long int i;

  if(DEBUG)
    printf("Searching beg = 0x%X to end = 0x%X with mask = 0x%X and cond = 0x%X\n", beg, end, mask, cond);
  
  for(i = beg; i <= end; i+= 0x0004){
      if(raw1394_start_read(handle, 0xffc0 | node, UCBASE+i, 4, &buffer, 0) < 0)
        return 0;
      raw1394_loop_iterate(handle);
      if(((byte_swap(buffer)&mask)>>mask_shift) == cond){
	return ((byte_swap(buffer)&0x00FFFFFF)*0x0004 + i);
      }
  }
  return 0;
}

quadlet_t byte_swap(quadlet_t d) // performs a byte swap if needed
{
  return ((d&0x000000FF)<<24|(d&0x0000FF00)<<8|(d&0x00FF0000)>>8|(d&0xFF000000)>>24);
}

// handlers
enum raw1394_iso_disposition my_iso_transmit_handler(raw1394handle_t h, unsigned char *d, unsigned int *len, unsigned char *tag, unsigned char *sy, int cycle, unsigned int dropped) // handler for iso transmittion
{
  unsigned int i = 0;

  if(DEBUG){
    printf("In iso transmitt handler\n");
    printf("Dropped packets %d, transmitting %d unsigned chars\n", dropped, *len);
  }

  if(data_index <= max_packet_size){
    *len = data_index;
  }

  if(data_index > max_packet_size) {
    *len = max_packet_size;
  }
  
  for(i = 0; i <= *len; i+=4 ) {
    switch(byte_order) {
    case BIG_ENDIAN:
      d[i] = (unsigned char)(data[data_index]&0x00FF);
      d[i+1] = (unsigned char)(data[data_index]&0xFF00>>8);
      d[i+2] = (unsigned char)(data[data_index+1]&0x00FF);
      d[i+3] = (unsigned char)(data[data_index+1]&0xFF>>8);
      break;
    case BIT_SWAP:
      d[i] = (unsigned char)(data[data_index+1]&0x00FF);
      d[i+1] = (unsigned char)(data[data_index+1]&0xFF00>>8);
      d[i+2] = (unsigned char)(data[data_index]&0x00FF);
      d[i+3] = (unsigned char)(data[data_index]&0xFF00>>8);
      break;
    case BYTE_SWAP:
      d[i] = (unsigned char)(data[data_index]&0xFF00>>8);
      d[i+1] = (unsigned char)(data[data_index]&0x00FF);
      d[i+2] = (unsigned char)(data[data_index+1]&0xFF00>>8);
      d[i+3] = (unsigned char)(data[data_index+1]&0x00FF);
      break;
    case LITTLE_ENDIAN:
      d[i] = (unsigned char)(data[data_index+1]&0xFF00>>8);
      d[i+1] = (unsigned char)(data[data_index+1]&0x00FF);
      d[i+2] = (unsigned char)(data[data_index]&0xFF00>>8);
      d[i+3] = (unsigned char)(data[data_index]&0x00FF);
      break;
    }
    data_index+2;
  }
  
  data_length -= *len;
  total += *len;

  return RAW1394_ISO_OK;
}

enum raw1394_iso_disposition my_iso_receive_handler(raw1394handle_t h, unsigned char *d, unsigned int len, unsigned char channel, unsigned char tag, unsigned char sy, unsigned int cycle, unsigned int dropped) // handler for iso reception
{
  unsigned int i = 0;

  if(DEBUG){
    printf("In iso recieve handler getting channel %c\n", channel);
    printf("Dropped packets %d, recieved %d unsigned chars\n", dropped, len);
  }
  
  if(data_length <= max_packet_size)
    len = data_length;

  if(data_length > max_packet_size)
    len = max_packet_size;
  
  for(i = 0; i <= len; i+=4) {
    switch(byte_order) {
    case BIG_ENDIAN:
      data[data_index] =(unsigned int) (d[i]<<8|d[i+1]);
      data[data_index+1] =(unsigned int) (d[i+2]<<8|d[i+3]); 
      break;
    case BIT_SWAP:
      data[data_index] =(unsigned int) (d[i+2]<8|d[i+3]);
      data[data_index+1] =(unsigned int) (d[i]<<8|d[i+1]); 
      break;
    case BYTE_SWAP:
      data[data_index] =(unsigned int) (d[i+1]<8|d[i]);
      data[data_index+1] =(unsigned int) (d[i+3]<<8|d[i+2]); 
      break;
    case LITTLE_ENDIAN:
      data[data_index] =(unsigned int) (d[i+3]<8|d[i+2]);
      data[data_index+1] =(unsigned int) (d[i+1]<<8|d[i]); 
      break;
    }
    data_index+2;
  }
  
  data_length-=len;
  total += len;

  return RAW1394_ISO_OK;
}

int my_bus_reset_handler(raw1394handle_t h, unsigned int gen)
{
  raw1394_update_generation(h, gen);

  if(UC1394_EXTERNAL_notifier != NULL)
    UC1394_EXTERNAL_notifier();

  return 1;
}

int my_iso_handler(raw1394handle_t h, int channel,  size_t length, quadlet_t *d)
{
  printf("In iso handler for channel %d, and length %d \n", channel, length);

  return 1;

}


