예제 #1
0
파일: echo.c 프로젝트: Milstein/trema
VALUE
echo_init( int argc, VALUE *argv, VALUE self ) {
  buffer *echo = NULL;
  Data_Get_Struct( self, buffer, echo );
  VALUE options = Qnil;

  if ( rb_scan_args( argc, argv, "01", &options ) == 0 ) {
    set_xid( echo, get_transaction_id() );
  }
  else {
    if ( options == Qnil ) {
      set_xid( echo, get_transaction_id() );
    }
    else if ( rb_obj_is_kind_of( options, rb_cInteger ) == Qtrue ) {
      validate_xid( options );
      set_xid( echo, ( uint32_t ) NUM2UINT( options ) );
    }
    else {
      Check_Type( options, T_HASH );
      VALUE tmp = Qnil;
      VALUE xid = Qnil;

      tmp = rb_hash_aref( options, ID2SYM( rb_intern( "transaction_id" ) ) );
      if ( tmp != Qnil ) {
        xid = tmp;
      }
      tmp = rb_hash_aref( options, ID2SYM( rb_intern( "xid" ) ) );
      if ( tmp != Qnil ) {
        xid = tmp;
      }
      if ( xid != Qnil ) {
        validate_xid( xid );
        set_xid( echo, ( uint32_t ) NUM2UINT( xid ) );
      }
      else {
        set_xid( echo, get_transaction_id() );
      }

      VALUE user_data = rb_hash_aref( options, ID2SYM( rb_intern( "user_data" ) ) );
      if ( user_data != Qnil ) {
        Check_Type( user_data, T_STRING );
        uint16_t length = ( uint16_t ) RSTRING_LEN( user_data );
        append_back_buffer( echo, length );
        set_length( echo, ( uint16_t ) ( sizeof( struct ofp_header ) + length ) );
        memcpy( ( char * ) echo->data + sizeof( struct ofp_header ), RSTRING_PTR( user_data ), length );
      }
    }
  }

  return self;
}
예제 #2
0
파일: vendor.c 프로젝트: kazuyas/trema
/*
 * Creates a Vendor Request message. This message can be used
 * to facilitate sending of vendor-defined arbitrary data.
 *
 * @overload initialize
 *   @example
 *     Vendor.new
 *
 * @overload initialize(options)
 *   @example
 *     Vendor.new(
 *       :vendor => 0x3000,
 *       :data => "deadbeef".unpack( "C*" ),
 *       :transaction_id => 123
 *     )
 *
 *   @param [Hash] options
 *     the options to create a message with.
 *   @option options [Number] :xid
 *   @option options [Number] :transaction_id
 *     an unsigned 32bit integer number associated with this message.
 *     if not specified, an auto-generated value is set.
 *   @option options [Number] :vendor
 *     the vendor identifier. If MSB is zero low order bytes are IEEE OUI. Otherwise defined by openflow.
 *   @option options [Array] :data
 *     a String that holds vendor's defined arbitrary length data.
 *
 * @raise [ArgumentError] if transaction ID is not an unsigned 32-bit integer.
 * @raise [ArgumentError] if user data is not an array of bytes.
 * @raise [TypeError] if options is not a hash.
 * @return [Vendor]
 */
static VALUE
vendor_init( int argc, VALUE *argv, VALUE self ) {
  buffer *vendor = NULL;
  Data_Get_Struct( self, buffer, vendor );
  VALUE options = Qnil;

  if ( rb_scan_args( argc, argv, "01", &options ) == 0 ) {
    set_xid( vendor, get_transaction_id() );
  }
  else {
    if ( options == Qnil ) {
      set_xid( vendor, get_transaction_id() );
    }
    else {
      if ( rb_scan_args( argc, argv, "01", &options ) == 1 ) {
        Check_Type( options, T_HASH );
        VALUE tmp = Qnil;
        VALUE xid = Qnil;

        tmp = rb_hash_aref( options, ID2SYM( rb_intern( "transaction_id" ) ) );
        if ( tmp != Qnil ) {
          xid = tmp;
        }
        tmp = rb_hash_aref( options, ID2SYM( rb_intern( "xid" ) ) );
        if ( tmp != Qnil ) {
          xid = tmp;
        }

        if ( xid != Qnil ) {
          validate_xid( xid );
          set_xid( vendor, ( uint32_t ) NUM2UINT( xid ) );
        }
        else {
          set_xid( vendor, get_transaction_id() );
        }

        tmp = rb_hash_aref( options, ID2SYM( rb_intern( "vendor" ) ) );
        if ( tmp != Qnil ) {
          ( ( struct ofp_vendor_header * ) ( vendor->data ) )->vendor = htonl( ( uint32_t ) NUM2UINT( tmp ) );
        }

        tmp = rb_hash_aref( options, ID2SYM( rb_intern( "data" ) ) );
        if ( tmp != Qnil ) {
          Check_Type( tmp, T_ARRAY );
          uint16_t length = ( uint16_t ) RARRAY_LEN( tmp );
          append_back_buffer( vendor, length );
          set_length( vendor, length );
          uint8_t *data = ( uint8_t * ) ( ( char * ) vendor->data + sizeof( struct ofp_vendor_header ) );
          int i;
          for ( i = 0; i < length; i++ ) {
            data[ i ] = ( uint8_t ) FIX2INT( RARRAY_PTR( tmp )[ i ] );
          }
        }
      }
    }
  }

  return self;
}
예제 #3
0
/*
 * Creates a {GetConfigRequest} instance to query configuration parameters
 * from the switch.
 *
 * @overload initialize()
 *   @example
 *     GetConfigRequest.new
 *
 * @overload initialize(transaction_id)
 *   @example
 *     GetConfigRequest.new( 123 )
 *   @param [Integer] transaction_id
 *     An unsigned 32-bit integer number associated with this message.
 *
 * @overload initialize(options)
 *   @example
 *     GetConfigRequest.new( :xid => 123 )
 *     GetConfigRequest.new( :transaction_id => 123 )
 *   @param [Hash] options
 *     the options to create a message with.
 *   @option options [Number] :xid an alias to transaction_id.
 *   @option options [Number] :transaction_id
 *     An unsigned 32-bit integer number associated with this message.
 *     If not specified, an auto-generated value is set.
 *
 * @raise [ArgumentError] if transaction ID is not an unsigned 32-bit integer.
 * @raise [TypeError] if argument is not a Integer or a Hash.
 * @return [GetConfigRequest]
 *     an object that encapsulates the +OFPT_GET_CONFIG+ OpenFlow message.
 */
static VALUE
get_config_request_init( int argc, VALUE *argv, VALUE self ) {
  buffer *get_config_request;
  Data_Get_Struct( self, buffer, get_config_request );
  VALUE options = Qnil;


  if ( rb_scan_args( argc, argv, "01", &options ) == 0 ) {
    set_xid( get_config_request, get_transaction_id() );
  }
  else {
    if ( options == Qnil ) {
      set_xid( get_config_request, get_transaction_id() );
    }
    else if ( rb_obj_is_kind_of( options, rb_cInteger ) == Qtrue ) {
      validate_xid( options );
      set_xid( get_config_request, ( uint32_t ) NUM2UINT( options ) );
    }
    else {
      Check_Type( options, T_HASH );
      VALUE tmp = Qnil;
      VALUE xid = Qnil;

      tmp = rb_hash_aref( options, ID2SYM( rb_intern( "transaction_id" ) ) );
      if ( tmp != Qnil ) {
        xid = tmp;
      }
      tmp = rb_hash_aref( options, ID2SYM( rb_intern( "xid" ) ) );
      if ( tmp != Qnil ) {
        xid = tmp;
      }

      if ( xid != Qnil ) {
        validate_xid( xid );
        set_xid( get_config_request, ( uint32_t ) NUM2UINT( xid ) );
      }
      else {
        set_xid( get_config_request, get_transaction_id() );
      }
    }
  }

  return self;
}
예제 #4
0
파일: error.c 프로젝트: Milstein/trema
/*
 * @overload initialize(options)
 *   @example
 *     Error.new(
 *       :type => OFPET_BAD_REQUEST,
 *       :code => OFPBRC_BAD_TYPE,
 *     )
 *     Error.new(
 *       :type => OFPET_BAD_REQUEST,
 *       :code => OFPBRC_BAD_TYPE,
 *       :transcation_id => 123
 *     )
 *     Error.new(
 *       :type => OFPET_BAD_REQUEST,
 *       :code => OFPBRC_BAD_TYPE,
 *       :transcation_id => 123
 *       :data => "Error!!"
 *     )
 *   @param [Hash] options
 *     the options to create a message with.
 *   @option options [Number] :type
 *     a command or action that failed.
 *   @option options [Number] :code
 *     the reason of the failed type error.
 *   @option options [String] :data
 *     a more user friendly explanation of the error. Defaults to nil
 *     if not specified.
 *   @option options [Number] :xid
 *   @option options [Number] :transaction_id
 *     An unsigned 32bit integer number associated with this message.
 *     If not specified, an auto-generated value is set.
 *   @raise [ArgumentError] if transaction ID is not an unsigned 32bit integer.
 *   @raise [ArgumentError] if type and code are not supplied.
 *   @raise [ArgumentError] if user data is not a string.
 *   @raise [TypeError] if options is not a hash.
 *   @return [Error]
 */
static VALUE
error_init( int argc, VALUE *argv, VALUE self ) {
  buffer *error = NULL;
  Data_Get_Struct( self, buffer, error );
  VALUE options;

  if ( rb_scan_args( argc, argv, "01", &options ) == 1 ) {
    Check_Type( options, T_HASH );
    VALUE tmp = Qnil;

    tmp = rb_hash_aref( options, ID2SYM( rb_intern( "type" ) ) );
    if ( tmp != Qnil ) {
      ( ( struct ofp_error_msg * ) error->data )->type = htons( ( uint16_t ) NUM2UINT( tmp ) );
    }
    else {
      rb_raise( rb_eArgError, "Type is a mandatory option" );
    }

    tmp = rb_hash_aref( options, ID2SYM( rb_intern( "code" ) ) );
    if ( tmp != Qnil ) {
      ( ( struct ofp_error_msg * ) error->data )->code = htons( ( uint16_t ) NUM2UINT( tmp ) );
    }
    else {
      rb_raise( rb_eArgError, "Code is a mandatory option" );
    }

    VALUE xid = Qnil;
    tmp = rb_hash_aref( options, ID2SYM( rb_intern( "transaction_id" ) ) );
    if ( tmp != Qnil ) {
      xid = tmp;
    }
    tmp = rb_hash_aref( options, ID2SYM( rb_intern( "xid" ) ) );
    if ( tmp != Qnil ) {
      xid = tmp;
    }
    if ( xid != Qnil ) {
      validate_xid( xid );
      set_xid( error, ( uint32_t ) NUM2UINT( xid ) );
    }
    else {
      set_xid( error, get_transaction_id() );
    }

    VALUE data = rb_hash_aref( options, ID2SYM( rb_intern( "data" ) ) );
    if ( data != Qnil ) {
      Check_Type( data, T_STRING );
      uint16_t length = ( uint16_t ) RSTRING_LEN( data );
      append_back_buffer( error, length );
      ( ( struct ofp_header * ) ( error->data ) )->length = htons( ( uint16_t ) ( offsetof( struct ofp_error_msg, data ) + length ) );
      memcpy( ( char * ) error->data + offsetof( struct ofp_error_msg, data ), RSTRING_PTR( data ), length );
    }