[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/recoord/python4yahdlc/develop/src/python4yahdlc.c [Back]  [Original]

#include 
#include "yahdlc.h"

#define MAX_FRAME_PAYLOAD       512
#define HEADERS_LENGTH          8

#define TOTAL_FRAME_LENGTH      MAX_FRAME_PAYLOAD + HEADERS_LENGTH

static PyObject *Yahdlc_MessageError;
static PyObject *Yahdlc_FCSError;

/* ---------- yahdlc functions ---------- */

/**
 * Retrieves data from the specified buffer containing the HDLC frame.
 */
static PyObject *get_data(PyObject *self, PyObject *args)
{
    int ret;
    const char *frame_data;
    char recv_data[TOTAL_FRAME_LENGTH];
    unsigned int buf_length = 0, recv_length = 0;
    yahdlc_control_t control;

    if (!PyArg_ParseTuple(args, "s#", &frame_data, &buf_length))
        return NULL;

    if (buf_length > TOTAL_FRAME_LENGTH)
    {
        PyErr_SetString(PyExc_ValueError, "buffer too long");
        return NULL;
    }

    ret = yahdlc_get_data(&control, frame_data, buf_length, recv_data, &recv_length);

    // If success.
    if (ret >= 0)
    {
        PyObject *t;

        t = PyTuple_New(4);
        PyTuple_SetItem(t, 0, PyBytes_FromStringAndSize(recv_data, recv_length));
        PyTuple_SetItem(t, 1, PyLong_FromUnsignedLong(control.frame));
        PyTuple_SetItem(t, 2, PyLong_FromUnsignedLong(control.seq_no));
        PyTuple_SetItem(t, 3, PyLong_FromUnsignedLong(ret));

        return t;
    }
    else if (ret == -EINVAL)
    {
        PyErr_SetString(PyExc_ValueError, "invalid parameter");
        return NULL;
    }
    else if (ret == -ENOMSG)
    {
        PyErr_SetString(Yahdlc_MessageError, "invalid message");
        return NULL;
    }
    // If the FCS is not valid, we return the sequence number
    // to be sent back as NACK.
    else if (ret == -EIO)
    {
        PyErr_SetObject(Yahdlc_FCSError, PyLong_FromUnsignedLong(control.seq_no));
        return NULL;
    }
    else
    {
        PyErr_SetString(PyExc_RuntimeError, "unknown error");
        return NULL;
    }
}

/**
 * Resets the values used by the 'yahdlc_get_data' function
 * to keep track of the received buffers.
 */
static PyObject *get_data_reset(PyObject *self, PyObject *args)
{
    yahdlc_get_data_reset();

    Py_RETURN_NONE;
}

/**
 * Creates an HDLC frame with the specified data buffer.
 */
static PyObject *frame_data(PyObject *self, PyObject *args)
{
    int ret;
    const char *send_data;
    char frame_data[TOTAL_FRAME_LENGTH];
    unsigned int data_length = 0, frame_length = 0, frame_type = YAHDLC_FRAME_DATA, seq_no = 0;
    yahdlc_control_t control;

    if (!PyArg_ParseTuple(args, "s#|II", &send_data, &data_length, &frame_type, &seq_no))
        return NULL;

    if (data_length > MAX_FRAME_PAYLOAD)
    {
        PyErr_SetString(PyExc_ValueError, "data too long");
        return NULL;
    }
    else if (frame_type != YAHDLC_FRAME_DATA && frame_type != YAHDLC_FRAME_ACK && frame_type != YAHDLC_FRAME_NACK)
    {
        PyErr_SetString(PyExc_ValueError, "bad frame type");
        return NULL;
    }
    else if (seq_no > 7)
    {
        PyErr_SetString(PyExc_ValueError, "invalid sequence number");
        return NULL;
    }

    control.frame = frame_type;
    control.seq_no = seq_no;
    ret = yahdlc_frame_data(&control, send_data, data_length, frame_data, &frame_length);

    // If success.
    if (ret == 0)
        return PyBytes_FromStringAndSize(frame_data, frame_length);
    else
    {
        PyErr_SetString(PyExc_ValueError, "invalid parameter");
        return NULL;
    }
}

/* ---------- Settings ---------- */

/**
 * Python module's methods.
 */
static PyMethodDef YahdlcMethods[] = {
    {"get_data", get_data, METH_VARARGS, "Retrieves data from the specified buffer containing the HDLC frame."},
    {"get_data_reset", get_data_reset, METH_VARARGS, "Resets the values used by the 'get_data' method to keep track of the received buffers."},
    {"frame_data", frame_data, METH_VARARGS, "Creates an HDLC frame with the specified data buffer."},
    {NULL, NULL, 0, NULL}
};

/**
 * Python module itself.
 */
static struct PyModuleDef yahdlc_module =
{
    PyModuleDef_HEAD_INIT,
    "yahdlc",
    "HDLC implementation",
    -1,
    YahdlcMethods
};

/**
 * Initialises the Python module.
 */
PyMODINIT_FUNC PyInit_yahdlc(void)
{
    PyObject *m;

    m = PyModule_Create(&yahdlc_module);

    if (m == NULL)
        return NULL;

    Yahdlc_MessageError = PyErr_NewException("yahdlc.MessageError", NULL, NULL);
    Py_INCREF(Yahdlc_MessageError);
    PyModule_AddObject(m, "MessageError", Yahdlc_MessageError);

    Yahdlc_FCSError = PyErr_NewException("yahdlc.FCSError", NULL, NULL);
    Py_INCREF(Yahdlc_FCSError);
    PyModule_AddObject(m, "FCSError", Yahdlc_FCSError);

    PyModule_AddIntConstant(m, "FRAME_DATA", YAHDLC_FRAME_DATA);
    PyModule_AddIntConstant(m, "FRAME_ACK", YAHDLC_FRAME_ACK);
    PyModule_AddIntConstant(m, "FRAME_NACK", YAHDLC_FRAME_NACK);

    return m;
}

Web Proxy Viewer  |  New URL  |  Original Page