Magic Lantern Firmware Wiki
Advertisement

This page describes the built-in networking capabilities of the Canon EOS 6D (WG).

Performance[]

Networking seems to be rather slow. Using a buffer size of 100 KB with a priority of 0x1D, it's only possible to send 100 MB in about 51 seconds. Higher priorities don't really help, as the network task priority seems to be quite low. Maybe it's possible to increase buffer sizes or alter the priority of the networking background task. With a priority of 0x10, I was only able to send ~ 22 MB of 100 MB, as the rest got dropped, but doing so took 71 seconds. -- Maqs

Networking functions[]

get_socket_list - netstat-like function[]

// All stubs for 6D.113
NSTUB(0x5A458, get_socket_list);
NSTUB(0xFF4F3CB0, NET_status_to_string); // called by netstat-function to get the corresponding status string to the status field of socket_info

// socket_status as in the lookup table refered to by NET_status_to_string
enum socket_status
{
    FREE = 0,
    CLOSED = 1,
    LISTEN = 2,
    SYNSENT = 3,
    SYNRCVD = 4,
    ESTABLISHED = 5,
    FINWAIT1 = 6,
    FINWAIT2 = 7,
    CLOSEWAIT = 8,
    LASTACK = 9,
    CLOSING = 10,
    TIMEWAIT = 11
};

struct socket_info
{
    // Those may be sockaddr structs. See example on how they are used.
    uint8_t local_a, local_b; // unknown
    uint16_t local_port;
    uint32_t local_ip;
    uint8_t local_tmp[6*4]; // unknown

    // Those may be sockaddr structs. See example on how they are used.
    uint8_t remote_a, remote_b; // unknown
    uint16_t remote_port;
    uint32_t remote_ip;
    uint8_t remote_tmp[6*4]; // unknown

    uint8_t flags[2*4]; // unknown
    uint32_t status;
} __attribute__((packed));

/*
int get_socket_list(struct socket_info *socket, int count);
- parameters:
    socket: pointer to already allocated array of 'struct socket_info'
    max: number of socket_info structs in allocated array
- returns: number of sockets or count in case there are more
    the array will contain information about the sockets
*/

get_arp_table - retrieve arp table entries[]

NSTUB(0x53F78, get_arp_table); // 6D.113

resolv - DNS resolver[]

NSTUB(0xFF6579A0, resolv); // 6D.113

/*

type = ["a"|"aaaa"|"ptr"|null]

??? resolv(char *host, char *type);
- 
- format of returned information still needs investigation
*/

Socket functions[]

// All stubs for 6D.113
NSTUB(0x543C4, socket_create); // socket_create(int a, int b, int c); returns file descriptor for socket (int).
NSTUB(0x545B4, socket_bind); // int socket_bind(int fd, struct sockaddr_..., int sockaddr_size). returns < 0 on error.
NSTUB(0x5462C, socket_listen); // int socket_listen(int fd, int backlog_maybe); returns < 0 on error.
NSTUB(0x546A8, socket_connect); // int socket_connect(int fd, struct sockaddr_..., int sockaddr_size). returns < 0 on error.
NSTUB(0x54760, socket_accept); // unknown so far
NSTUB(0x54968, inet_recv); // int inet_recv(int fd, char *buf, int buf_size); returns number of bytes received or < 0 on error.
NSTUB(0x54AB0, recvfrom);
NSTUB(0x54C18, inet_send); // int inet_send(int fd, char *buf, int buf_size); returns number of bytes sent or < 0 on error.
NSTUB(0x54CE4, sendto);
NSTUB(0x550DC, socket_set_option);
NSTUB(0x5529C, socket_shutdown);
NSTUB(0xFF151C34, socket_close);

Error handling[]

int *get_errno_ptr - get 'errno' for current (!) task

NSTUB(0xFF0C89DC, get_errno_ptr);

Example usage[]

This example shows a little echo client (!), as socket_listen() still needs investigation.

static int echo_connect_fd;

static void echo_connect_task(void * unused)
{
    char buf[100];

    TASK_LOOP
    {
        int bytes_received = inet_recv(echo_connect_fd, buf, sizeof(buf) - 1);

        if (bytes_received <= 0)
        {
            int *errno = errno_get_pointer_to();

            console_printf("inet_recv() error: %d, errno %d\n", bytes_received, *errno);
            break;
        }

        buf[bytes_received] = '\0';

        console_printf("Received: %s\n", buf);

        int ret = inet_send(echo_connect_fd, buf, bytes_received);

        if (ret < 0)
        {
            int *errno = errno_get_pointer_to();

            console_printf("inet_send() error: %d, errno %d\n", ret, *errno);
            break;
        }

        msleep(100);
    }

    // close socket
    socket_close(echo_connect_fd);
}


void echo_connect()
{
    echo_connect_fd = socket_create(1, 1, 0);

    if (echo_connect_fd < 0)
    {
        int *errno = errno_get_pointer_to();

        console_printf("socket_create() error: %d!\n", *errno);
    } else
    {
        char sockaddr[8];

        // 1 = IPv4, 2 = IPv6, 3 = Ethernet
        sockaddr[0] = 0x00;
        sockaddr[1] = 0x01;

        // port 4112
        sockaddr[2] = 0x10; // low byte
        sockaddr[3] = 0x10; // high byte

        // ip address: 10.0.0.1
        sockaddr[4] = 10;
        sockaddr[5] = 0;
        sockaddr[6] = 0;
        sockaddr[7] = 1;

        int res = socket_connect(echo_connect_fd, sockaddr, 8);

        if (res < 0)
        {
            int *errno = errno_get_pointer_to();

            console_printf("socket_connect() error: %d!\n", errno);
        }

        task_create("echo_connect_task", 0x1d, 0x1000, echo_connect_task, 0);
    }
}
Advertisement