static enum SUB_STATE_RETURN write_state_machine(SSL *s)
{
    STATEM *st = &s->statem;
    int ret;
    enum WRITE_TRAN (*transition)(SSL *s);
    enum WORK_STATE (*pre_work)(SSL *s, enum WORK_STATE wst);
    enum WORK_STATE (*post_work)(SSL *s, enum WORK_STATE wst);
    int (*construct_message)(SSL *s);
    void (*cb) (const SSL *ssl, int type, int val) = NULL;
    if (s->info_callback != NULL)
        cb = s->info_callback;
    else if (s->ctx->info_callback != NULL)
        cb = s->ctx->info_callback;
    if(s->server) {
        transition = NULL;
        pre_work = NULL;
        post_work = NULL;
        construct_message = NULL;
    } else {
        transition = NULL;
        pre_work = NULL;
        post_work = NULL;
        construct_message = NULL;
    }
    while(1) {
        switch(st->write_state) {
        case WRITE_STATE_TRANSITION:
            if (cb != NULL) {
                if (s->server)
                    cb(s, SSL_CB_ACCEPT_LOOP, 1);
                else
                    cb(s, SSL_CB_CONNECT_LOOP, 1);
            }
            switch(transition(s)) {
            case WRITE_TRAN_CONTINUE:
                st->write_state = WRITE_STATE_PRE_WORK;
                st->write_state_work = WORK_MORE_A;
                break;
            case WRITE_TRAN_FINISHED:
                return SUB_STATE_FINISHED;
                break;
            default:
                return SUB_STATE_ERROR;
            }
            break;
        case WRITE_STATE_PRE_WORK:
            switch(st->write_state_work = pre_work(s, st->write_state_work)) {
            default:
                return SUB_STATE_ERROR;
            case WORK_FINISHED_CONTINUE:
                st->write_state = WRITE_STATE_SEND;
                break;
            case WORK_FINISHED_STOP:
                return SUB_STATE_END_HANDSHAKE;
            }
            if(construct_message(s) == 0)
                return SUB_STATE_ERROR;
        case WRITE_STATE_SEND:
            if (SSL_IS_DTLS(s) && st->use_timer) {
                dtls1_start_timer(s);
            }
            ret = statem_do_write(s);
            if (ret <= 0) {
                return SUB_STATE_ERROR;
            }
            st->write_state = WRITE_STATE_POST_WORK;
            st->write_state_work = WORK_MORE_A;
        case WRITE_STATE_POST_WORK:
            switch(st->write_state_work = post_work(s, st->write_state_work)) {
            default:
                return SUB_STATE_ERROR;
            case WORK_FINISHED_CONTINUE:
                st->write_state = WRITE_STATE_TRANSITION;
                break;
            case WORK_FINISHED_STOP:
                return SUB_STATE_END_HANDSHAKE;
            }
            break;
        default:
            return SUB_STATE_ERROR;
        }
    }
}
['static enum SUB_STATE_RETURN write_state_machine(SSL *s)\n{\n    STATEM *st = &s->statem;\n    int ret;\n    enum WRITE_TRAN (*transition)(SSL *s);\n    enum WORK_STATE (*pre_work)(SSL *s, enum WORK_STATE wst);\n    enum WORK_STATE (*post_work)(SSL *s, enum WORK_STATE wst);\n    int (*construct_message)(SSL *s);\n    void (*cb) (const SSL *ssl, int type, int val) = NULL;\n    if (s->info_callback != NULL)\n        cb = s->info_callback;\n    else if (s->ctx->info_callback != NULL)\n        cb = s->ctx->info_callback;\n    if(s->server) {\n        transition = NULL;\n        pre_work = NULL;\n        post_work = NULL;\n        construct_message = NULL;\n    } else {\n        transition = NULL;\n        pre_work = NULL;\n        post_work = NULL;\n        construct_message = NULL;\n    }\n    while(1) {\n        switch(st->write_state) {\n        case WRITE_STATE_TRANSITION:\n            if (cb != NULL) {\n                if (s->server)\n                    cb(s, SSL_CB_ACCEPT_LOOP, 1);\n                else\n                    cb(s, SSL_CB_CONNECT_LOOP, 1);\n            }\n            switch(transition(s)) {\n            case WRITE_TRAN_CONTINUE:\n                st->write_state = WRITE_STATE_PRE_WORK;\n                st->write_state_work = WORK_MORE_A;\n                break;\n            case WRITE_TRAN_FINISHED:\n                return SUB_STATE_FINISHED;\n                break;\n            default:\n                return SUB_STATE_ERROR;\n            }\n            break;\n        case WRITE_STATE_PRE_WORK:\n            switch(st->write_state_work = pre_work(s, st->write_state_work)) {\n            default:\n                return SUB_STATE_ERROR;\n            case WORK_FINISHED_CONTINUE:\n                st->write_state = WRITE_STATE_SEND;\n                break;\n            case WORK_FINISHED_STOP:\n                return SUB_STATE_END_HANDSHAKE;\n            }\n            if(construct_message(s) == 0)\n                return SUB_STATE_ERROR;\n        case WRITE_STATE_SEND:\n            if (SSL_IS_DTLS(s) && st->use_timer) {\n                dtls1_start_timer(s);\n            }\n            ret = statem_do_write(s);\n            if (ret <= 0) {\n                return SUB_STATE_ERROR;\n            }\n            st->write_state = WRITE_STATE_POST_WORK;\n            st->write_state_work = WORK_MORE_A;\n        case WRITE_STATE_POST_WORK:\n            switch(st->write_state_work = post_work(s, st->write_state_work)) {\n            default:\n                return SUB_STATE_ERROR;\n            case WORK_FINISHED_CONTINUE:\n                st->write_state = WRITE_STATE_TRANSITION;\n                break;\n            case WORK_FINISHED_STOP:\n                return SUB_STATE_END_HANDSHAKE;\n            }\n            break;\n        default:\n            return SUB_STATE_ERROR;\n        }\n    }\n}']