bool FirewirePort::Init(void)
{
    // create firewire port handle
    handle = raw1394_new_handle();
    handle_bc = raw1394_new_handle();
    if (!handle || !handle_bc) {
        outStr << "FirewirePort: could not create handle" << std::endl;
        return false;
    }

    PortListType::const_iterator it;
    for (it = PortList.begin(); it != PortList.end(); it++) {
        if ((*it)->PortNum == PortNum)
            outStr << "WARNING: Firewire port " << PortNum
                   << " is already used (be careful about thread safety)" << std::endl;
        if ((*it)->handle == handle) // should never happen
            outStr << "WARNING: Firewire handle is already used" << std::endl;
    }
    PortList.push_back(this);

    memset(Node2Board, BoardIO::MAX_BOARDS, sizeof(Node2Board));

    // set the bus reset handler
    old_reset_handler = raw1394_set_bus_reset_handler(handle, reset_handler);
    old_reset_handler = raw1394_set_bus_reset_handler(handle_bc, reset_handler);

    // get number of ports
    int nports = raw1394_get_port_info(handle, NULL, 0);
    outStr << "FirewirePort: number of ports = " << nports << std::endl;
    if (nports < PortNum) {
        outStr << "FirewirePort: port " << PortNum << " does not exist" << std::endl;
        raw1394_destroy_handle(handle);
        handle = NULL;
        return false;
    }

    if (raw1394_set_port(handle, PortNum) || raw1394_set_port(handle_bc, PortNum)) {
        outStr << "FirewirePort: error setting port to " << PortNum << std::endl;
        raw1394_destroy_handle(handle);
        raw1394_destroy_handle(handle_bc);
        handle = NULL;
        handle_bc = NULL;
        return false;
    }
    outStr << "FirewirePort: successfully initialized port " << PortNum << std::endl;

    // stop cycle start packet
    StopCycleStartPacket();

    return ScanNodes();
}
int main(int argc, char** argv)
{
    int rc; /**< return code */
    int port = 0;  /*!< fw handle port number */
    int nodeid = 0;   /*!< arm server node id */

    // parse command line (port number)
    opterr = 0;  // getopt no err output
    const char short_options[] = "hp:n:";
    int next_opt;
    do {
        next_opt = getopt(argc, argv, short_options);
        switch(next_opt)
        {
        case 'h':
            print_usage();
            return EXIT_SUCCESS;
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'n':
            nodeid = atoi(optarg);
            break;
        case '?':
            std::cerr << "Invalid argument" << std::endl;
            break;
        default:
            break;
        }
    }
    while(next_opt != -1);


    // ----- Get handle and set port for the handle -------
    // create handle
    handle = raw1394_new_handle();
    if (handle == NULL) {
        std::cerr << "**** Error: could not create 1394 handle " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    // get port number & sanity check
    int numPorts = raw1394_get_port_info(handle, NULL, 0);
    if (port < 0 || port >= numPorts) {
        std::cerr << "Invalid port number" << std::endl;
        return EXIT_FAILURE;
    }

    // let user to choose which port to use
    rc = raw1394_set_port(handle, port);
    if (rc) {
        std::cerr << "**** Error: failed to set port " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }


    // -------- Set FireWire bus reset handler --------

    // set bus reset handler
    raw1394_set_bus_reset_handler(handle, my_bus_reset_handler);



    // ----------------------------------------------------------------------------
    // Start tutorial 6 isochronous send
    // ----------------------------------------------------------------------------

    /**
     * raw1394_iso_xmit_init - initialize isochronous transmission
     * @handle: libraw1394 handle
     * @handler: handler function for queueing packets
     * @buf_packets: number of isochronous packets to buffer
     * @max_packet_size: largest packet you need to handle, in bytes
     * (not including the isochronous header)
     * @channel: isochronous channel on which to transmit
     * @speed: speed at which to transmit
     * @irq_interval: maximum latency of wake-ups, in packets (-1 if you don't care)
     *
     * Allocates all user and kernel resources necessary for isochronous transmission.
     * Channel and bandwidth allocation at the IRM is not performed.
     *
     * Returns: 0 on success or -1 on failure (sets errno)
     **/
    size_t length;
    unsigned char channel, tag, sy;
    unsigned char buffer[BUF_SIZE + BUF_HEAD];
    channel = 5;
    tag = 6;
    sy = 7;

    // ----- transmitting end -------------
    rc = raw1394_iso_xmit_init(handle,      // 1394 handle
                               NULL,        // xmit handler
                               BUFFER,      // iso packets to buffer
                               MAX_PACKET,  // max packet size
                               channel,           // just pick 5 for fun
                               RAW1394_ISO_SPEED_400,
                               -1);         // irq_interval
    if (rc) {
        perror("raw1394_iso_xmit_init");
        exit(1);
    }
    rc = raw1394_iso_xmit_start(handle, -1, -1);
    if (rc) {
        perror("raw1394_iso_xmit_start");
        exit(1);
    }

    quadlet_t data = 0x0;
    while (true) {
        rc = raw1394_iso_xmit_write(handle,
                                    (unsigned char *)&data,
                                    4,
                                    tag,
                                    sy);
        if (rc) {
            perror("\nraw1394_iso_xmit_write");
            break;
        }
//        data++;
//        std::cout << "data = " << data << std::endl;
    }

    // stop, clean up & exit
    raw1394_iso_stop(handle);
    raw1394_iso_shutdown(handle);
    raw1394_destroy_handle(handle);

    return EXIT_SUCCESS;
}
static gboolean
gst_hdv1394src_start (GstBaseSrc * bsrc)
{
    GstHDV1394Src *src = GST_HDV1394SRC (bsrc);
    int control_sock[2];

    src->connected = FALSE;

    if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
        goto socket_pair;

    READ_SOCKET (src) = control_sock[0];
    WRITE_SOCKET (src) = control_sock[1];

    if (fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
        GST_ERROR_OBJECT (src, "failed to make read socket non-blocking: %s",
                          g_strerror (errno));
    if (fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
        GST_ERROR_OBJECT (src, "failed to make write socket non-blocking: %s",
                          g_strerror (errno));

    src->handle = raw1394_new_handle ();

    if (!src->handle) {
        if (errno == EACCES)
            goto permission_denied;
        else if (errno == ENOENT)
            goto not_found;
        else
            goto no_handle;
    }

    src->num_ports = raw1394_get_port_info (src->handle, src->pinfo, 16);

    if (src->num_ports == 0)
        goto no_ports;

    if (src->use_avc || src->port == -1)
        src->avc_node = gst_hdv1394src_discover_avc_node (src);

    /* lets destroy handle and create one on port
       this is more reliable than setting port on
       the existing handle */
    raw1394_destroy_handle (src->handle);
    src->handle = raw1394_new_handle_on_port (src->port);
    if (!src->handle)
        goto cannot_set_port;

    raw1394_set_userdata (src->handle, src);
    raw1394_set_bus_reset_handler (src->handle, gst_hdv1394src_bus_reset);

    {
        nodeid_t m_node = (src->avc_node | 0xffc0);
        int m_channel = -1;
        int m_bandwidth = 0;
        int m_outputPort = -1;
        int m_inputPort = -1;

        m_channel = iec61883_cmp_connect (src->handle, m_node, &m_outputPort,
                                          raw1394_get_local_id (src->handle), &m_inputPort, &m_bandwidth);

        if (m_channel >= 0) {
            src->channel = m_channel;
        }
    }


    if ((src->iec61883mpeg2 =
                iec61883_mpeg2_recv_init (src->handle,
                                          gst_hdv1394src_iec61883_receive, src)) == NULL)
        goto cannot_initialise_dv;

#if 0
    raw1394_set_iso_handler (src->handle, src->channel,
                             gst_hdv1394src_iso_receive);
#endif

    GST_DEBUG_OBJECT (src, "successfully opened up 1394 connection");
    src->connected = TRUE;

    if (iec61883_mpeg2_recv_start (src->iec61883mpeg2, src->channel) != 0)
        goto cannot_start;
#if 0
    if (raw1394_start_iso_rcv (src->handle, src->channel) < 0)
        goto cannot_start;
#endif

    if (src->use_avc) {
        raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);

        GST_LOG ("We have an avc_handle");

        /* start the VCR */
        if (avc_handle) {
            if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
                    && avc1394_vcr_is_playing (avc_handle, src->avc_node)
                    != AVC1394_VCR_OPERAND_PLAY_FORWARD) {
                GST_LOG ("Calling avc1394_vcr_play()");
                avc1394_vcr_play (avc_handle, src->avc_node);
            }
            raw1394_destroy_handle (avc_handle);
        } else {
            GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
                                g_strerror (errno));
        }
    }

    return TRUE;

socket_pair:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
                           GST_ERROR_SYSTEM);
        return FALSE;
    }
permission_denied:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
        return FALSE;
    }
not_found:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), GST_ERROR_SYSTEM);
        return FALSE;
    }
no_handle:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
                           ("can't get raw1394 handle (%s)", g_strerror (errno)));
        return FALSE;
    }
no_ports:
    {
        raw1394_destroy_handle (src->handle);
        src->handle = NULL;
        GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
                           ("no ports available for raw1394"));
        return FALSE;
    }
cannot_set_port:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
                           ("can't set 1394 port %d", src->port));
        return FALSE;
    }
cannot_start:
    {
        raw1394_destroy_handle (src->handle);
        src->handle = NULL;
        iec61883_mpeg2_close (src->iec61883mpeg2);
        src->iec61883mpeg2 = NULL;
        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
                           ("can't start 1394 iso receive"));
        return FALSE;
    }
cannot_initialise_dv:
    {
        raw1394_destroy_handle (src->handle);
        src->handle = NULL;
        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
                           ("can't initialise iec61883 hdv"));
        return FALSE;
    }
}
int main(int argc, char** argv)
{
    int rc; /**< return code */
    int port = 0;  /*!< fw handle port number */

    // parse command line (port number)
    opterr = 0;  // getopt no err output
    const char short_options[] = "p:";
    int next_opt;
    do {
        next_opt = getopt(argc, argv, short_options);
        switch(next_opt)
        {
        case 'p':
            port = atoi(optarg);
            break;
        case '?':
            std::cerr << "Invalid argument" << std::endl;
            break;
        default:
            break;
        }
    }
    while(next_opt != -1);


    // Setup signal handler to exit on Ctrl-C
    signal(SIGINT, signal_handler);


    // ----- Get handle and set port for the handle -------
    // create handle
    handle = raw1394_new_handle();
    if (handle == NULL) {
        std::cerr << "**** Error: could not create 1394 handle " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    // get port number & sanity check
    int numPorts = raw1394_get_port_info(handle, NULL, 0);
    if (port < 0 || port >= numPorts) {
        std::cerr << "Invalid port number" << std::endl;
        return EXIT_FAILURE;
    }

    // let user to choose which port to use
    rc = raw1394_set_port(handle, 0);
    if (rc) {
        std::cerr << "**** Error: failed to set port " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }


    // -------- Set FireWire bus reset handler --------
    // set bus reset handler
    bus_reset_handler_t old_bus_reset_handler;
    old_bus_reset_handler = raw1394_set_bus_reset_handler(handle, my_bus_reset_handler);



    // ----------------------------------------------------------------------------
    // Start tutorial 2 arm server
    // ----------------------------------------------------------------------------


    // -------- Register arm register to handle arm request --------
    const nodeaddr_t arm_start_addr = 0xffffff000000;  // arm start address
    const size_t arm_length = 4;  // arm length to register

    // arm initial buffer
    byte_t arm_init_buffer[arm_length];
    memset(arm_init_buffer, 0x02, arm_length);  // set inital value to all 0x02

    // setup arm request handle
    raw1394_arm_reqhandle arm_reqhandle;
    char my_arm_callback_context[] = "my_arm_callback_context";
    arm_reqhandle.pcontext = my_arm_callback_context;
    arm_reqhandle.arm_callback = my_arm_req_callback;

    int access_mode = RAW1394_ARM_WRITE|RAW1394_ARM_READ;   // allow read and write transaction

    rc = raw1394_arm_register(handle,  // fw handle
                              arm_start_addr, // arm start address
			      arm_length * 4, // arm_length quadlet * 4 to bytes
			      arm_init_buffer,  // arm init buffer value
                              (octlet_t) &arm_reqhandle,  // arm request handler
                              access_mode,   // access permission
                              access_mode,   // client handler will be notified
                              0);            // client handler will need to handle these transactions

    if (rc) {
        std::cerr << "**** Error: failed to setup arm register, error " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    // -------- Read from this arm buffer ---------
    // NOTE: this is a simple way to test if
    const size_t arm_read_size = 4;
    byte_t arm_read_buffer[arm_read_size];

    rc = raw1394_arm_get_buf(handle, arm_start_addr, arm_read_size, arm_read_buffer);
    if (rc) {
        std::cerr << "**** Error: failed to read arm register, error " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    } else {
        // if success then print value
        std::cout << "ARM buffer read value: \n";
        for (size_t i = 0; i < arm_read_size; i++) {
            std::cout << std::hex << " " << (int)arm_read_buffer[i];
        }
        std::cout << std::endl;
    }

    // -------- Set value to this arm buffer ---------
    const size_t arm_write_size = 4;
    byte_t arm_write_buffer[arm_write_size] = {0x11, 0x22, 0x33, 0x44};
    rc = raw1394_arm_set_buf(handle, arm_start_addr, arm_write_size, arm_write_buffer);
    if (rc) {
        std::cerr << "**** Error: failed to set arm register, error " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }


    // --------- Now read the value back from buffer ------
    rc = raw1394_arm_get_buf(handle, arm_start_addr, arm_read_size, arm_read_buffer);
    if (rc) {
        std::cerr << "**** Error: failed to read arm register, error " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    } else {
        // if success then print value
        std::cout << "ARM buffer read value: \n";
        for (size_t i = 0; i < arm_read_size; i++) {
            std::cout << std::hex << " " << (int)arm_read_buffer[i];
        }
        std::cout << std::endl;
    }


    // --------- Infinite raw1394 event loop ----------

    std::cout << "--------- Now start arm server -----------" << std::endl;
    std::cout << " node id = " << raw1394_get_local_id(handle) << std::endl;

    while (true)
    {
        raw1394_loop_iterate(handle);
    }

    // clean up & exit
    raw1394_destroy_handle(handle);

    return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
    int rc; /**< return code */
    int port = 0;  /*!< fw handle port number */
    int nodeid = 0;   /*!< arm server node id */

    // parse command line (port number)
    opterr = 0;  // getopt no err output
    const char short_options[] = "hp:n:";
    int next_opt;
    do {
        next_opt = getopt(argc, argv, short_options);
        switch(next_opt)
        {
        case 'h':
            print_usage();
            return EXIT_SUCCESS;
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'n':
            nodeid = atoi(optarg);
            break;
        case '?':
            std::cerr << "Invalid argument" << std::endl;
            break;
        default:
            break;
        }
    }
    while(next_opt != -1);


    // ----- Get handle and set port for the handle -------
    // create handle
    handle = raw1394_new_handle();
    if (handle == NULL) {
        std::cerr << "**** Error: could not create 1394 handle " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    // get port number & sanity check
    int numPorts = raw1394_get_port_info(handle, NULL, 0);
    if (port < 0 || port >= numPorts) {
        std::cerr << "Invalid port number" << std::endl;
        return EXIT_FAILURE;
    }

    // let user to choose which port to use
    rc = raw1394_set_port(handle, port);
    if (rc) {
        std::cerr << "**** Error: failed to set port " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }


    // -------- Set FireWire bus reset handler --------

    // set bus reset handler
    raw1394_set_bus_reset_handler(handle, my_bus_reset_handler);



    // ----------------------------------------------------------------------------
    // Start tutorial 4 async broadcast
    // ----------------------------------------------------------------------------

    /**
     *
     */
    // ----- receving end -------------
    unsigned char channel = 0x5;
    raw1394_iso_dma_recv_mode mode = RAW1394_DMA_DEFAULT;

    raw1394_iso_recv_init(handle,
                          my_iso_recv_handler,
                          BUFFER,      // buf_packets
                          PACKET_MAX,  // max_packet_size
                          channel,     // channel
                          mode,        // dma mode
                          -1);         // irq_interval

    // start receiving
    raw1394_iso_recv_start(handle, -1, -1, 0);
    while (true)
    {
        rc = raw1394_loop_iterate(handle);
        if (rc) break;
    }

    // stop, clean up & exit
    raw1394_iso_stop(handle);
    raw1394_iso_shutdown(handle);
    raw1394_destroy_handle(handle);

    return EXIT_SUCCESS;
}