Пример #1
0
Файл: check.c Проект: BrEacK/mc
static cb_ret_t
check_callback (Widget * w, widget_msg_t msg, int parm)
{
    WCheck *c = (WCheck *) w;
    Dlg_head *h = c->widget.owner;

    switch (msg)
    {
    case WIDGET_HOTKEY:
        if (c->text.hotkey != NULL)
        {
            if (g_ascii_tolower ((gchar) c->text.hotkey[0]) == parm)
            {
                check_callback (w, WIDGET_KEY, ' ');    /* make action */
                return MSG_HANDLED;
            }
        }
        return MSG_NOT_HANDLED;

    case WIDGET_KEY:
        if (parm != ' ')
            return MSG_NOT_HANDLED;
        c->state ^= C_BOOL;
        c->state ^= C_CHANGE;
        h->callback (h, w, DLG_ACTION, 0, NULL);
        check_callback (w, WIDGET_FOCUS, ' ');
        return MSG_HANDLED;

    case WIDGET_CURSOR:
        widget_move (&c->widget, 0, 1);
        return MSG_HANDLED;

    case WIDGET_FOCUS:
    case WIDGET_UNFOCUS:
    case WIDGET_DRAW:
        widget_selectcolor (w, msg == WIDGET_FOCUS, FALSE);
        widget_move (&c->widget, 0, 0);
        tty_print_string ((c->state & C_BOOL) ? "[x] " : "[ ] ");
        hotkey_draw (w, c->text, msg == WIDGET_FOCUS);
        return MSG_HANDLED;

    case WIDGET_DESTROY:
        release_hotkey (c->text);
        return MSG_HANDLED;

    default:
        return default_proc (msg, parm);
    }
}
Пример #2
0
/*
 * have to sort this one out.
 */
void handle_ipprog(node n, artnet_packet p) {

  if (check_callback(n, p, n->callbacks.ipprog))
    return;

  printf("in ipprog\n");
}
Пример #3
0
int handle_tod_control(node n, artnet_packet p) {
  int i;
  int ret = ARTNET_EOK;

  if (check_callback(n, p, n->callbacks.todcontrol))
    return ARTNET_EOK;

  for (i=0; i < ARTNET_MAX_PORTS; i++) {
    if (n->ports.out[i].port_addr == p->data.todcontrol.address &&
        n->ports.out[i].port_enabled) {

      if (p->data.todcontrol.cmd == ARTNET_TOD_FLUSH) {
        // flush tod for this port
        flush_tod(&n->ports.out[i].port_tod);

        //initiate full rdm discovery
        // do callback here
        if (n->callbacks.rdm_init_c.fh != NULL)
          n->callbacks.rdm_init_c.fh(n, i, n->callbacks.rdm_init_c.data);

        // not really sure what to do here, the calling app should do a rdm
        // init and call artnet_add_rdm_devices() which will send a tod data
        // but do we really trust the caller ?
        // Instead we'll send an empty tod data and then another one a bit later
        // when our tod is populated
      }
      // reply with tod
      ret = ret || artnet_tx_tod_data(n, i);
    }
  }
  return ret;
}
Пример #4
0
static void write_conv(PurpleConversation *conv, const char *who, const char *alias,
			const char *message, PurpleMessageFlags flags, time_t mtime)
{	
  if (im_handler != Qnil) {
    PurpleAccount* account = purple_conversation_get_account(conv);
    if (strcmp(purple_account_get_protocol_id(account), "prpl-msn") == 0 &&
         (strstr(message, "Message could not be sent") != NULL ||
          strstr(message, "Message was not sent") != NULL ||
          strstr(message, "Message may have not been sent") != NULL
         )
        ) {
      /* I have seen error like 'msn: Connection error from Switchboard server'.
       * In that case, libpurple will notify user with two regular im message.
       * The first message is an error message, the second one is the original message that failed to send.
       */
      notify_message(PURPLE_CONNECTION_ERROR_NETWORK_ERROR, message, purple_account_get_protocol_id(account), who);
    } else {
      VALUE args[3];
      args[0] = Data_Wrap_Struct(cAccount, NULL, NULL, account);
      args[1] = rb_str_new2(who);
      args[2] = rb_str_new2(message);
      check_callback(im_handler, "im_handler");
      rb_funcall2(im_handler, CALL, 3, args);
    }
  }
}
Пример #5
0
static void* request_action(const char *title, const char *primary, const char *secondary,
                            int default_action,
                            PurpleAccount *account, 
                            const char *who, 
                            PurpleConversation *conv,
                            void *user_data, 
                            size_t action_count, 
                            va_list actions)
{
  if (request_handler != Qnil) {
	  VALUE args[4];
    args[0] = rb_str_new2(NULL == title ? "" : title);
    args[1] = rb_str_new2(NULL == primary ? "" : primary);
    args[2] = rb_str_new2(NULL == secondary ? "" : secondary);
    args[3] = rb_str_new2(NULL == who ? "" : who);
    check_callback(request_handler, "request_handler");
    VALUE v = rb_funcall2(request_handler, CALL, 4, args);
	  
	  if (v != Qnil && v != Qfalse) {
	    /*const char *text =*/ va_arg(actions, const char *);
	    GCallback ok_cb = va_arg(actions, GCallback);
      ((PurpleRequestActionCb)ok_cb)(user_data, default_action);
    }
  }
  
  return NULL;
}
Пример #6
0
/*
 * Handle an artpoll packet
 */
int handle_poll(node n, artnet_packet p) {
  // run callback if defined
  if (check_callback(n, p, n->callbacks.poll))
    return ARTNET_EOK;

  if (n->state.node_type != ARTNET_RAW) {
    //if we're told to unicast further replies
    if (p->data.ap.ttm & TTM_REPLY_MASK) {
      n->state.reply_addr = p->from;
    } else {
      n->state.reply_addr.s_addr = n->state.bcast_addr.s_addr;
    }

    // if we are told to send updates when node conditions change
    if (p->data.ap.ttm & TTM_BEHAVIOUR_MASK) {
      n->state.send_apr_on_change = TRUE;
    } else {
      n->state.send_apr_on_change = FALSE;
    }

    return artnet_tx_poll_reply(n, TRUE);

  }
  return ARTNET_EOK;
}
Пример #7
0
/***
 * handle tod request packet
 */
int handle_tod_request(node n, artnet_packet p) {
  int i, j, limit;
  int ret = ARTNET_EOK;

  if (check_callback(n, p, n->callbacks.todrequest))
    return ARTNET_EOK;

  if (n->state.node_type != ARTNET_NODE)
    return ARTNET_EOK;

  // limit to 32
  limit = min(ARTNET_MAX_RDM_ADCOUNT, p->data.todreq.adCount);

  // this should always be true
  if (p->data.todreq.command == 0x00) {
    for (i=0; i < limit; i++) {
      for (j=0; j < ARTNET_MAX_PORTS; j++) {
        if (n->ports.out[j].port_addr == p->data.todreq.address[i] &&
            n->ports.out[j].port_enabled) {
          // reply with tod
          ret = ret || artnet_tx_tod_data(n, j);
        }
      }
    }
  }

//  err_warn("tod request received but command is 0x%02hhx rather than 0x00\n", p->data.todreq.command);
  return ret;
}
Пример #8
0
/*
 * handle art input.
 * ArtInput packets can disable input ports.
 */
int _artnet_handle_input(node n, artnet_packet p) {
  int i, ports, ret;

  if (check_callback(n, p, n->callbacks.input))
    return ARTNET_EOK;

  // servers (and raw nodes) don't respond to input packets
  if (n->state.node_type != ARTNET_NODE && n->state.node_type != ARTNET_MSRV)
    return ARTNET_EOK;

  ports = min( p->data.ainput.numbports, ARTNET_MAX_PORTS);
  for (i =0; i < ports; i++) {
    if (p->data.ainput.input[i] & PORT_DISABLE_MASK) {
      // disable
      n->ports.in[i].port_status = n->ports.in[i].port_status | PORT_STATUS_DISABLED_MASK;
    } else {
      // enable
      n->ports.in[i].port_status = n->ports.in[i].port_status & ~PORT_STATUS_DISABLED_MASK;
    }
  }

  if ((ret = artnet_tx_build_art_poll_reply(n)))
    return ret;

  return artnet_tx_poll_reply(n, TRUE);
}
Пример #9
0
static void signed_off(PurpleConnection* connection)
{
  VALUE args[1];
  args[0] = Data_Wrap_Struct(cAccount, NULL, NULL, purple_connection_get_account(connection));
  check_callback(signed_off_handler, "signed_off_handler");
  rb_funcall2(signed_off_handler, CALL, 1, args);
}
Пример #10
0
/*
 * handle an art poll reply
 */
void handle_reply(node n, artnet_packet p) {
  // update the node list
  artnet_nl_update(&n->node_list, p);

  // run callback if defined
  if (check_callback(n, p, n->callbacks.reply))
    return;
}
Пример #11
0
static gboolean
do_timeout(gpointer data)
{
	VALUE handler = data;
	check_callback(handler, "timer_handler");
	VALUE v = rb_funcall(handler, CALL, 0, 0);
	return (v == Qtrue);
}
Пример #12
0
static void update_blist(PurpleBuddyList *list, PurpleBlistNode *node)
{
	if (blist_update_handler != Qnil && PURPLE_BLIST_NODE_IS_BUDDY(node)) {
		PurpleBuddy *buddy = (PurpleBuddy *)node;
		check_callback(blist_update_handler, "blist_update_handler");
		VALUE args[2];
		args[0] = RB_BLIST_BUDDY(buddy);
		args[1] = Data_Wrap_Struct(cAccount, NULL, NULL, purple_buddy_get_account(buddy));
		rb_funcall2(blist_update_handler, CALL, 2, args);		
	}
}
Пример #13
0
/**
 * handle tod data packet
 *
 * we don't maintain a tod of whats out on the network,
 * the calling app can deal with this.
 */
void handle_tod_data(node n, artnet_packet p) {

  if (check_callback(n, p, n->callbacks.toddata))
    return;

  // pass data to app

//  if (n->callbacks.rdm_tod_c.fh != NULL)
//    n->callbacks.rdm_tod_c.fh(n, i, n->callbacks.rdm_tod_c.data);

  return;
}
Пример #14
0
Файл: check.c Проект: BrEacK/mc
static int
check_event (Gpm_Event * event, void *data)
{
    Widget *w = (Widget *) data;

    if (!mouse_global_in_widget (event, w))
        return MOU_UNHANDLED;

    if ((event->type & (GPM_DOWN | GPM_UP)) != 0)
    {
        dlg_select_widget (w);
        if ((event->type & GPM_UP) != 0)
        {
            check_callback (w, WIDGET_KEY, ' ');
            check_callback (w, WIDGET_FOCUS, 0);
            w->owner->callback (w->owner, w, DLG_POST_KEY, ' ', NULL);
        }
    }

    return MOU_NORMAL;
}
Пример #15
0
/**
 * handle rdm packet
 *
 */
void handle_rdm(node n, artnet_packet p) {


  if (check_callback(n, p, n->callbacks.rdm))
    return;

  printf("rdm data\n");

  // hell dodgy
  if (n->callbacks.rdm_c.fh != NULL)
    n->callbacks.rdm_c.fh(n, p->data.rdm.address, p->data.rdm.data, ARTNET_MAX_RDM_DATA, n->callbacks.rdm_c.data);

  return;
}
Пример #16
0
void report_disconnect(PurpleConnection *gc, PurpleConnectionError reason, const char *text)
{
  if (Qnil != connection_error_handler) {
    VALUE args[3];
    args[0] = Data_Wrap_Struct(cAccount, NULL, NULL, purple_connection_get_account(gc));
    args[1] = INT2FIX(reason);
    args[2] = rb_str_new2(text);
    check_callback(connection_error_handler, "connection_error_handler");
    VALUE v = rb_funcall2(connection_error_handler, CALL, 3, args);
    
    if (v != Qnil && v != Qfalse) {
      finch_connection_report_disconnect(gc, reason, text);
    }
  }
}
Пример #17
0
/**
 * handle an firmware reply
 */
int handle_firmware_reply(node n, artnet_packet p) {
  node_entry_private_t *ent;

  // run callback if defined
  if (check_callback(n, p, n->callbacks.firmware_reply))
    return ARTNET_EOK;

  ent = find_entry_from_ip(&n->node_list, p->from);

  // node doesn't exist in our list, or we're not doing a transfer to this node
  if (ent== NULL || ent->firmware.bytes_total == 0)
    return ARTNET_EOK;

  // three types of response, ALLGOOD,  BLOCKGOOD and FIRMFAIL
  if (p->data.firmwarer.type == ARTNET_FIRMWARE_ALLGOOD) {

    if (ent->firmware.bytes_total == ent->firmware.bytes_current) {
      // transfer complete

      // do the callback
      if (ent->firmware.callback != NULL)
        ent->firmware.callback(n, ARTNET_FIRMWARE_ALLGOOD, ent->firmware.user_data);

      memset(&ent->firmware, 0x0, sizeof(firmware_transfer_t));

    } else {
      // random ALLGOOD received, don't let this abort the transfer
      printf("FIRMWARE_ALLGOOD received before transfer completed\n");
    }

  } else if (p->data.firmwarer.type == ARTNET_FIRMWARE_FAIL) {

    // do the callback
    if (ent->firmware.callback != NULL)
        ent->firmware.callback(n, ARTNET_FIRMWARE_FAIL, ent->firmware.user_data);

    // cancel transfer
    memset(&ent->firmware, 0x0, sizeof(firmware_transfer_t));

  } else if (p->data.firmwarer.type == ARTNET_FIRMWARE_BLOCKGOOD) {
    // send the next block (only if we're not done yet)
    if (ent->firmware.bytes_total != ent->firmware.bytes_current) {
      return artnet_tx_firmware_packet(n, &ent->firmware);
    }
  }
  return ARTNET_EOK;
}
Пример #18
0
static void* notify_message(PurpleNotifyMsgType type, 
	const char *title,
	const char *primary, 
	const char *secondary)
{
  if (notify_message_handler != Qnil) {
    VALUE args[4];
    args[0] = INT2FIX(type);
    args[1] = rb_str_new2(NULL == title ? "" : title);
    args[2] = rb_str_new2(NULL == primary ? "" : primary);
    args[3] = rb_str_new2(NULL == secondary ? "" : secondary);
    check_callback(notify_message_handler, "notify_message_handler");
    rb_funcall2(notify_message_handler, CALL, 4, args);
  }
  
  return NULL;
}
Пример #19
0
static void _read_socket_handler(gpointer notused, int socket, PurpleInputCondition condition)
{
  char message[4096] = {0};
  int i = recv(socket, message, sizeof(message) - 1, 0);
  if (i > 0) {
    purple_debug_info("purple_ruby", "recv %d: %d\n", socket, i);
    
    gpointer str = g_hash_table_lookup(data_hash_table, (gpointer)socket);
    if (NULL == str) rb_raise(rb_eRuntimeError, "can not find socket: %d", socket);
    rb_str_append((VALUE)str, rb_str_new2(message));
  } else {
    purple_debug_info("purple_ruby", "close connection %d: %d %d\n", socket, i, errno);
    
    gpointer str = g_hash_table_lookup(data_hash_table, (gpointer)socket);
    if (NULL == str) {
      purple_debug_warning("purple_ruby", "can not find socket in data_hash_table %d\n", socket);
      return;
    }
    
    gpointer purple_fd = g_hash_table_lookup(fd_hash_table, (gpointer)socket);
    if (NULL == purple_fd) {
      purple_debug_warning("purple_ruby", "can not find socket in fd_hash_table %d\n", socket);
      return;
    }
    
    g_hash_table_remove(fd_hash_table, (gpointer)socket);
    g_hash_table_remove(data_hash_table, (gpointer)socket);
    purple_input_remove((guint)purple_fd);
    close(socket);
    
    VALUE args[1];
    args[0] = (VALUE)str;
    check_callback(ipc_handler, "ipc_handler");
    rb_funcall2(ipc_handler, CALL, 1, args);
  }
}
Пример #20
0
/*
 * handle a art dmx packet
 */
void handle_dmx(node n, artnet_packet p) {
  int i, data_length;
  output_port_t *port;
  in_addr_t ipA, ipB;

  // run callback if defined
  if (check_callback(n, p, n->callbacks.dmx))
    return;

  data_length = (int) bytes_to_short(p->data.admx.lengthHi,
                                     p->data.admx.length);
  data_length = min(data_length, ARTNET_DMX_LENGTH);

  // find matching output ports
  for (i = 0; i < ARTNET_MAX_PORTS; i++) {
    // if the addr matches and this port is enabled
    if (p->data.admx.universe == n->ports.out[i].port_addr &&
        n->ports.out[i].port_enabled) {

      port = &n->ports.out[i];
      ipA = port->ipA.s_addr;
      ipB = port->ipB.s_addr;

      // ok packet matches this port
      n->ports.out[i].port_status = n->ports.out[i].port_status | PORT_STATUS_ACT_MASK;

      /**
       * 9 cases for merging depending on what the stored ips are.
       * here's the truth table
       *
       *
       * \   ipA   #           #            #             #
       *  ------   #   empty   #            #             #
       *   ipB  \  #   ( 0 )   #    p.from  #   ! p.from  #
       * ##################################################
       *           # new node  # continued  # start       #
       *  empty    # first     #  trans-    #  merge      #
       *   (0)     #   packet  #   mission  #             #
       * ##################################################
       *           #continued  #            # cont        #
       *  p.from   # trans-    # invalid!   #  merge      #
       *           #  mission  #            #             #
       * ##################################################
       *           # start     # cont       #             #
       * ! p.from  #  merge    #   merge    # discard     #
       *           #           #            #             #
       * ##################################################
       *
       * The merge exits when:
       *   o ACCancel command is received in an ArtAddress packet
       *       (this is done in handle_address )
       *   o no data is recv'ed from one source in 10 seconds
       *
       */

      check_merge_timeouts(n,i);

      if (ipA == 0 && ipB == 0) {
        // first packet recv on this port
        port->ipA.s_addr = p->from.s_addr;
        port->timeA = time(NULL);

        memcpy(&port->dataA, &p->data.admx.data, data_length);
        port->length = data_length;
        memcpy(&port->data, &p->data.admx.data, data_length);
      }
      else if (ipA == p->from.s_addr && ipB == 0) {
        //continued transmission from the same ip (source A)

        port->timeA = time(NULL);
        memcpy(&port->dataA, &p->data.admx.data, data_length);
        port->length = data_length;
        memcpy(&port->data, &p->data.admx.data, data_length);
      }
      else if (ipA == 0 && ipB == p->from.s_addr) {
        //continued transmission from the same ip (source B)

        port->timeB = time(NULL);
        memcpy(&port->dataB, &p->data.admx.data, data_length);
        port->length = data_length;
        memcpy(&port->data, &p->data.admx.data, data_length);
      }
      else if (ipA != p->from.s_addr  && ipB == 0) {
        // new source, start the merge
        port->ipB.s_addr = p->from.s_addr;
        port->timeB = time(NULL);
        memcpy(&port->dataB, &p->data.admx.data,data_length);
        port->length = data_length;

        // merge, newest data is port B
        merge(n,i,data_length, port->dataB);

        // send reply if needed

      }
      else if (ipA == 0 && ipB == p->from.s_addr) {
        // new source, start the merge
        port->ipA.s_addr = p->from.s_addr;
        port->timeB = time(NULL);
        memcpy(&port->dataB, &p->data.admx.data,data_length);
        port->length = data_length;

        // merge, newest data is portA
        merge(n,i,data_length, port->dataA);

        // send reply if needed
      }
      else if (ipA == p->from.s_addr && ipB != p->from.s_addr) {
        // continue merge
        port->timeA = time(NULL);
        memcpy(&port->dataA, &p->data.admx.data,data_length);
        port->length = data_length;

        // merge, newest data is portA
        merge(n,i,data_length, port->dataA);

      }
      else if (ipA != p->from.s_addr && ipB == p->from.s_addr) {
        // continue merge
        port->timeB = time(NULL);
        memcpy(&port->dataB, &p->data.admx.data,data_length);
        port->length = data_length;

        // merge newest data is portB
        merge(n,i,data_length, port->dataB);

      }
      else if (ipA == p->from.s_addr && ipB == p->from.s_addr) {
//        err_warn("In handle_dmx, source matches both buffers, this shouldn't be happening!\n");

      }
      else if (ipA != p->from.s_addr && ipB != p->from.s_addr) {
//        err_warn("In handle_dmx, more than two sources, discarding data\n");

      }
      else {
//        err_warn("In handle_dmx, no cases matched, this shouldn't happen!\n");

      }

      // do the dmx callback here
      if (n->callbacks.dmx_c.fh != NULL)
        n->callbacks.dmx_c.fh(n,i, n->callbacks.dmx_c.data);
    }
  }
  return;
}
Пример #21
0
// THIS NEEDS TO BE CHECKED FOR BUFFER OVERFLOWS
// IMPORTANT!!!!
int handle_firmware(node n, artnet_packet p) {
  int length, offset, block_length, total_blocks, block_id;
  artnet_firmware_status_code response_code = ARTNET_FIRMWARE_FAIL;

  // run callback if defined
  if (check_callback(n, p, n->callbacks.firmware))
    return ARTNET_EOK;

  /*
   * What happens if an upload is less than 512 bytes ?????
   */

  if ( p->data.firmware.type == ARTNET_FIRMWARE_FIRMFIRST ||
       p->data.firmware.type == ARTNET_FIRMWARE_UBEAFIRST) {
    // a new transfer is initiated

    if (n->firmware.peer.s_addr == 0) {
      //new transfer
      // these are 2 byte words, so we get a total of 1k of data per packet
      length = artnet_misc_nbytes_to_32( p->data.firmware.length ) *
        sizeof(p->data.firmware.data[0]);

      // set parameters
      n->firmware.peer.s_addr = p->from.s_addr;
      n->firmware.data = malloc(length);

      if (n->firmware.data  == NULL) {
        artnet_error_malloc();
        return ARTNET_EMEM;
      }
      n->firmware.bytes_total = length;
      n->firmware.last_time = time(NULL);
      n->firmware.expected_block = 1;

      // check if this is a ubea upload or not
      if (p->data.firmware.type == ARTNET_FIRMWARE_FIRMFIRST)
        n->firmware.ubea = 0;
      else
        n->firmware.ubea = 1;

      // take the minimum of the total length and the max packet size
      block_length = min((unsigned int) length, ARTNET_FIRMWARE_SIZE *
        sizeof(p->data.firmware.data[0]));

      memcpy(n->firmware.data, p->data.firmware.data, block_length);
      n->firmware.bytes_current = block_length;

      if (block_length == length) {
        // this is the first and last packet
        // upload was less than 1k bytes
        // this behaviour isn't in the spec, presumably no firmware will be less that 1k
        response_code = ARTNET_FIRMWARE_ALLGOOD;

        // do the callback here
        if (n->callbacks.firmware_c.fh != NULL)
          n->callbacks.firmware_c.fh(n,
                                     n->firmware.ubea,
                                     n->firmware.data,
                                     n->firmware.bytes_total,
                                     n->callbacks.firmware_c.data);

      } else {
        response_code = ARTNET_FIRMWARE_BLOCKGOOD;
      }

    } else {
      // already in a transfer
      printf("First, but already for a packet\n");

      // send a failure
      response_code = ARTNET_FIRMWARE_FAIL;
    }

  } else if (p->data.firmware.type == ARTNET_FIRMWARE_FIRMCONT ||
             p->data.firmware.type == ARTNET_FIRMWARE_UBEACONT) {
    // continued transfer
    length = artnet_misc_nbytes_to_32(p->data.firmware.length) *
      sizeof(p->data.firmware.data[0]);
    total_blocks = length / ARTNET_FIRMWARE_SIZE / 2 + 1;
    block_length = ARTNET_FIRMWARE_SIZE * sizeof(uint16_t);
    block_id = p->data.firmware.blockId;

    // ok the blockid field is only 1 byte, so it wraps back to 0x00 we
    // need to watch for this
    if (n->firmware.expected_block > UINT8_MAX &&
       (n->firmware.expected_block % (UINT8_MAX+1)) == p->data.firmware.blockId) {

      block_id = n->firmware.expected_block;
    }
    offset = block_id * ARTNET_FIRMWARE_SIZE;

    if (n->firmware.peer.s_addr == p->from.s_addr &&
        length == n->firmware.bytes_total &&
        block_id < total_blocks-1) {

      memcpy(n->firmware.data + offset, p->data.firmware.data, block_length);
      n->firmware.bytes_current += block_length;
      n->firmware.expected_block++;

      response_code = ARTNET_FIRMWARE_BLOCKGOOD;
    } else {
      printf("cont, ips don't match or length has changed or out of range block num\n" );

      // in a transfer not from this ip
      response_code = ARTNET_FIRMWARE_FAIL;
    }

  } else if (p->data.firmware.type == ARTNET_FIRMWARE_FIRMLAST ||
             p->data.firmware.type == ARTNET_FIRMWARE_UBEALAST) {
    length = artnet_misc_nbytes_to_32( p->data.firmware.length) *
      sizeof(p->data.firmware.data[0]);
    total_blocks = length / ARTNET_FIRMWARE_SIZE / 2 + 1;

    // length should be the remaining data
    block_length = n->firmware.bytes_total % (ARTNET_FIRMWARE_SIZE * sizeof(uint16_t));
    block_id = p->data.firmware.blockId;

    // ok the blockid field is only 1 byte, so it wraps back to 0x00 we
    // need to watch for this
    if (n->firmware.expected_block > UINT8_MAX &&
       (n->firmware.expected_block % (UINT8_MAX+1)) == p->data.firmware.blockId) {

      block_id = n->firmware.expected_block;
    }
    offset = block_id * ARTNET_FIRMWARE_SIZE;

    if (n->firmware.peer.s_addr == p->from.s_addr &&
        length == n->firmware.bytes_total &&
        block_id == total_blocks-1) {

      // all the checks work out
      memcpy(n->firmware.data + offset, p->data.firmware.data, block_length);
      n->firmware.bytes_current += block_length;

      // do the callback here
      if (n->callbacks.firmware_c.fh != NULL)
        n->callbacks.firmware_c.fh(n, n->firmware.ubea,
          n->firmware.data,
          n->firmware.bytes_total / sizeof(p->data.firmware.data[0]),
          n->callbacks.firmware_c.data);

      // reset values and free
      reset_firmware_upload(n);

      response_code = ARTNET_FIRMWARE_ALLGOOD;
      printf("Firmware upload complete\n");

    } else if (n->firmware.peer.s_addr != p->from.s_addr) {
      // in a transfer not from this ip
      printf("last, ips don't match\n" );
      response_code = ARTNET_FIRMWARE_FAIL;
    } else if (length != n->firmware.bytes_total) {
      // they changed the length mid way thru a transfer
      printf("last, lengths have changed %d %d\n", length, n->firmware.bytes_total);
      response_code = ARTNET_FIRMWARE_FAIL;
    } else if (block_id != total_blocks -1) {
      // the blocks don't match up
      printf("This is the last block, but not according to the lengths %d %d\n", block_id, total_blocks -1);
      response_code = ARTNET_FIRMWARE_FAIL;
    }
  }

  return artnet_tx_firmware_reply(n, p->from.s_addr, response_code);
}
Пример #22
0
static hosting_version_t *
hosting_load_and_check_plugin (
  char *file_name, char *function_name,
  unit_version_t *dock_version, void *appdata)
{
  void *dll;
  unit_check_t *check_callback;
  unit_version_t *res;
  char *fname = file_name;
  hosting_version_t *hres;
  FILE *test;
  char *sys_err;
  test = fopen (fname, "rb");
  if (NULL == test)
    {
      hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
      res = &(hres->hv_pversion);
      res->uv_filename = strdup (fname);
      res->uv_load_error = "Unable to locate file";
      return hres;
    }
  fclose (test);
  dll = DLL_OPEN_GLOBAL (fname);
  if (NULL == dll)
    {
      hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
      res = &(hres->hv_pversion);
      res->uv_filename = strdup (fname);
      sys_err = DLL_ERROR ();
      res->uv_load_error = strdup (sys_err ? sys_err : "");
      return hres;
    }
  check_callback = (unit_check_t *) DLL_PROC (dll, function_name);
  if (NULL == check_callback)
    {
      char *err;
      sys_err = DLL_ERROR ();
      err = strdup (sys_err ? sys_err : "");
      DLL_CLOSE (dll);
      hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
      res = &(hres->hv_pversion);
      res->uv_filename = strdup (fname);
      res->uv_load_error = err;
      return hres;
    }
  res = check_callback (dock_version, appdata);
  if (!res)
    {
      hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
      res = &(hres->hv_pversion);
      res->uv_filename = strdup (fname);
      res->uv_load_error = "incorrect initialization";
      return hres;
    }
  res->uv_filename = strdup (fname);
  if (NULL != res->uv_load_error)
    {
      char *err = strdup (res->uv_load_error);
      DLL_CLOSE (dll);
      hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
      res = &(hres->hv_pversion);
      res->uv_filename = strdup (fname);
      res->uv_load_error = err;
      return hres;
    }

  if (strcmp (res->uv_title, HOSTING_TITLE))
    {
      DLL_CLOSE (dll);
      hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
      res = &(hres->hv_pversion);
      res->uv_filename = strdup (fname);
      res->uv_load_error = "Invalid hosting module loaded";
      return hres;
    }

  if (NULL != res->uv_gate)
    {
      if (_gate_export (res->uv_gate))
	{
	  DLL_CLOSE (dll);
	  hres = (hosting_version_t *) calloc (1, sizeof (hosting_version_t));
	  res = &(hres->hv_pversion);
	  res->uv_filename = strdup (fname);
	  res->uv_load_error = "Loaded plugin requires core functionality not provided by main application";
	  return hres;
	}
    }

  hres = (hosting_version_t *) res;

  SET_DLL_PROC (hres, http_handler, HOSTING_HTTP_HANDLER, 1);
  SET_DLL_PROC (hres, client_attach, HOSTING_CLIENT_ATTACH, 1);
  SET_DLL_PROC (hres, client_detach, HOSTING_CLIENT_DETACH, 1);
  SET_DLL_PROC (hres, client_free, HOSTING_CLIENT_FREE, 1);
  SET_DLL_PROC (hres, client_clone, HOSTING_CLIENT_CLONE, 0);
  return hres;
}
Пример #23
0
/*
 * The main handler for an artnet packet. calls
 * the appropriate handler function
 */
int handle(node n, artnet_packet p) {

  if (check_callback(n, p, n->callbacks.recv))
    return 0;

  switch (p->type) {
    case ARTNET_POLL:
      handle_poll(n, p);
      break;
    case ARTNET_REPLY:
      handle_reply(n,p);
      break;
    case ARTNET_DMX:
      handle_dmx(n, p);
      break;
    case ARTNET_ADDRESS:
      handle_address(n, p);
      break;
    case ARTNET_INPUT:
      _artnet_handle_input(n, p);
      break;
    case ARTNET_TODREQUEST:
      handle_tod_request(n, p);
      break;
    case ARTNET_TODDATA:
      handle_tod_data(n, p);
      break;
    case ARTNET_TODCONTROL:
      handle_tod_control(n, p);
      break;
    case ARTNET_RDM:
      handle_rdm(n, p);
      break;
    case ARTNET_VIDEOSTEUP:
      printf("vid setup\n");
      break;
    case ARTNET_VIDEOPALETTE:
      printf("video palette\n");
      break;
    case ARTNET_VIDEODATA:
      printf("video data\n");
      break;
    case ARTNET_MACMASTER:
      printf("mac master\n");
      break;
    case ARTNET_MACSLAVE:
      printf("mac slave\n");
      break;
    case ARTNET_FIRMWAREMASTER:
      handle_firmware(n, p);
      break;
    case ARTNET_FIRMWAREREPLY:
      handle_firmware_reply(n, p);
      break;
    case ARTNET_IPPROG :
      handle_ipprog(n, p);
      break;
    case ARTNET_IPREPLY:
      printf("ip reply\n");
      break;
    case ARTNET_MEDIA:
      printf("media \n");
      break;
    case ARTNET_MEDIAPATCH:
      printf("media patch\n");
      break;
    case ARTNET_MEDIACONTROLREPLY:
      printf("media control reply\n");
      break;
    default:
      n->state.report_code = ARTNET_RCPARSEFAIL;
      printf("artnet but not yet implemented!, op was %hx\n", p->type);
  }
  return 0;
}
Пример #24
0
unit_version_t *uv_load_and_check_plugin(
  char *file_name, char *function_name,
  unit_version_t *dock_version, void *appdata)
{
  char fname[255];
  int fnameidx;
  unit_version_t *res;
  FILE *test;
  int so_ext_idx;
  void *dll;
  unit_check_t *check_callback;
  for (fnameidx = 0; fnameidx < (255-5); fnameidx++)
    {
      char c = file_name[fnameidx];
      if ('\0' == c)
	break;
      fname[fnameidx] = (('\\' == c) ? '/' : c);
    }
  for (so_ext_idx = 0; so_ext_idx < so_extensions_n; so_ext_idx++)
    {
      strcpy (fname+fnameidx, so_extensions[so_ext_idx]);
      test = fopen (fname, "rb");
      if (test)
	break;
    }
  if (NULL == test)
    {
      res = calloc (1, sizeof (unit_version_t));
      res->uv_filename = (char *) strdup (fname);
      res->uv_load_error = "Unable to locate file";
      return res;
    }
  fclose (test);
  /* open so */
  dll = DLL_OPEN_GLOBAL (fname);
  if (NULL == dll)
    {
      res = calloc (1, sizeof (unit_version_t));
      res->uv_filename = strdup (fname);
      res->uv_load_error = strdup (DLL_ERROR());
      return res;
    }
  if (NULL == function_name)
    {
      res = calloc (1, sizeof (unit_version_t));
      res->uv_filename = strdup (fname);
      res->uv_load_error = NULL;
      return res;
    }
  check_callback = (unit_check_t *) DLL_PROC (dll, function_name);
  if (NULL == check_callback)
    {
      char * err = strdup (DLL_ERROR());
      DLL_CLOSE (dll);
      res = calloc (1, sizeof (unit_version_t));
      res->uv_filename = strdup (fname);
      res->uv_load_error = err;
      return res;
    }
  res = check_callback (dock_version, appdata);
  res->uv_filename = strdup (fname);
  if (NULL != res->uv_load_error)
    {
      /* FreeLibrary (dll); -- result we will return now is in dll's address space */
      return res;
    }
  if (NULL == res->uv_gate)
    {
      /* FreeLibrary (dll); -- result we will return now is in dll's address space */
      res->uv_load_error = "Loaded plugin is not compatible with your version of OS";
      return res;
    }
  if (0 != _gate_export (res->uv_gate))
    {
      /* FreeLibrary (dll); -- result we will return now is in dll's address space */
      res->uv_load_error = "Loaded plugin requires core functionality not provided by main application";
      return res;
    }
  return res;
}
Пример #25
0
/**
 * handle art address packet.
 * This can reprogram certain nodes settings such as short/long name, port
 * addresses, subnet address etc.
 *
 */
int handle_address(node n, artnet_packet p) {
  int i, old_subnet;
  int addr[ARTNET_MAX_PORTS];
  int ret;

  if (check_callback(n, p, n->callbacks.address))
    return ARTNET_EOK;

  // servers (and raw nodes) don't respond to address packets
  if (n->state.node_type == ARTNET_SRV || n->state.node_type == ARTNET_RAW)
    return ARTNET_EOK;

  // reprogram shortname if required
  if (p->data.addr.shortname[0] != PROGRAM_DEFAULTS &&
      p->data.addr.shortname[0] != PROGRAM_NO_CHANGE) {
    memcpy(&n->state.short_name, &p->data.addr.shortname, ARTNET_SHORT_NAME_LENGTH);
    n->state.report_code = ARTNET_RCSHNAMEOK;
  }
  // reprogram long name if required
  if (p->data.addr.longname[0] != PROGRAM_DEFAULTS &&
      p->data.addr.longname[0] != PROGRAM_NO_CHANGE) {
    memcpy(&n->state.long_name, &p->data.addr.longname, ARTNET_LONG_NAME_LENGTH);
    n->state.report_code = ARTNET_RCLONAMEOK;
  }

  // first of all store existing port addresses
  // then we can work out if they change
  for (i=0; i< ARTNET_MAX_PORTS; i++) {
    addr[i] = n->ports.in[i].port_addr;
  }

  // program subnet
  old_subnet = p->data.addr.subnet;
  if (p->data.addr.subnet == PROGRAM_DEFAULTS) {
    // reset to defaults
    n->state.subnet = n->state.default_subnet;
    n->state.subnet_net_ctl = FALSE;

  } else if (p->data.addr.subnet & PROGRAM_CHANGE_MASK) {
    n->state.subnet = p->data.addr.subnet & ~PROGRAM_CHANGE_MASK;
    n->state.subnet_net_ctl = TRUE;
  }

  // check if subnet has actually changed
  if (old_subnet != n->state.subnet) {
    // if it does we need to change all port addresses
    for(i=0; i< ARTNET_MAX_PORTS; i++) {
      n->ports.in[i].port_addr = _make_addr(n->state.subnet, n->ports.in[i].port_addr);
      n->ports.out[i].port_addr = _make_addr(n->state.subnet, n->ports.out[i].port_addr);
    }
  }

  // program swins
  for (i =0; i < ARTNET_MAX_PORTS; i++) {
    if (p->data.addr.swin[i] == PROGRAM_NO_CHANGE)  {
      continue;
    } else if (p->data.addr.swin[i] == PROGRAM_DEFAULTS) {
      // reset to defaults
      n->ports.in[i].port_addr = _make_addr(n->state.subnet, n->ports.in[i].port_default_addr);
      n->ports.in[i].port_net_ctl = FALSE;

    } else if ( p->data.addr.swin[i] & PROGRAM_CHANGE_MASK) {
      n->ports.in[i].port_addr = _make_addr(n->state.subnet, p->data.addr.swin[i]);
      n->ports.in[i].port_net_ctl = TRUE;
    }
  }

  // program swouts
  for (i =0; i < ARTNET_MAX_PORTS; i++) {
    if (p->data.addr.swout[i] == PROGRAM_NO_CHANGE) {
      continue;
    } else if (p->data.addr.swout[i] == PROGRAM_DEFAULTS) {
      // reset to defaults
      n->ports.out[i].port_addr = _make_addr(n->state.subnet, n->ports.out[i].port_default_addr);
      n->ports.out[i].port_net_ctl = FALSE;
      n->ports.out[i].port_enabled = TRUE;
    } else if ( p->data.addr.swout[i] & PROGRAM_CHANGE_MASK) {
      n->ports.out[i].port_addr = _make_addr(n->state.subnet, p->data.addr.swout[i]);
      n->ports.in[i].port_net_ctl = TRUE;
      n->ports.out[i].port_enabled = TRUE;
    }
  }

  // reset sequence numbers if the addresses change
  for (i=0; i< ARTNET_MAX_PORTS; i++) {
    if (addr[i] != n->ports.in[i].port_addr)
      n->ports.in[i].seq = 0;
  }

  // check command
  switch (p->data.addr.command) {
    case ARTNET_PC_CANCEL:
      // fix me
      break;
    case ARTNET_PC_RESET:
      n->ports.out[0].port_status = n->ports.out[0].port_status & ~PORT_STATUS_DMX_SIP & ~PORT_STATUS_DMX_TEST & ~PORT_STATUS_DMX_TEXT;
      // need to force a rerun of short tests here
      break;
    case ARTNET_PC_MERGE_LTP_O:
      n->ports.out[0].merge_mode = ARTNET_MERGE_LTP;
      n->ports.out[0].port_status = n->ports.out[0].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_LTP_1:
      n->ports.out[1].merge_mode = ARTNET_MERGE_LTP;
      n->ports.out[1].port_status = n->ports.out[1].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_LTP_2:
      n->ports.out[2].merge_mode = ARTNET_MERGE_LTP;
      n->ports.out[2].port_status = n->ports.out[2].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_LTP_3:
      n->ports.out[3].merge_mode = ARTNET_MERGE_LTP;
      n->ports.out[3].port_status = n->ports.out[3].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_HTP_0:
      n->ports.out[0].merge_mode = ARTNET_MERGE_HTP;
      n->ports.out[0].port_status = n->ports.out[0].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_HTP_1:
      n->ports.out[1].merge_mode = ARTNET_MERGE_HTP;
      n->ports.out[1].port_status = n->ports.out[1].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_HTP_2:
      n->ports.out[2].merge_mode = ARTNET_MERGE_HTP;
      n->ports.out[2].port_status = n->ports.out[2].port_status | PORT_STATUS_LPT_MODE;
      break;
    case ARTNET_PC_MERGE_HTP_3:
      n->ports.out[3].merge_mode = ARTNET_MERGE_HTP;
      n->ports.out[3].port_status = n->ports.out[3].port_status | PORT_STATUS_LPT_MODE;
      break;

  }

  if (n->callbacks.program_c.fh != NULL)
    n->callbacks.program_c.fh(n , n->callbacks.program_c.data);

  if ((ret = artnet_tx_build_art_poll_reply(n)))
    return ret;

  return artnet_tx_poll_reply(n, TRUE);
}