esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% micosmntsrv.mac
#%NAME%
#  Macro motors on Micos motion server 
#%CATEGORY% Positioning
# 
#%DESCRIPTION%
#  Macros defining macro motors on the micos motion server 
#  like for example for the SpaceFAB system.
#  Communication is based on ethernet sockets
#
#%END%

def micos_mtnsrv_config(mnum, type, p1, p2, p3) '{
    global MICOS_MTNSRV[]
    local ret unit aux[] ntok host ctrl str allhosts port socket

    if (MICOS_MTNSRV["debug"]) {
        printf("micos_mtnsrv_config: ")
        printf("ADDR=%s, mnum=%s, type=%s, p1=%s, p2=%s, p3=%s\n", \
               micos_mtnsrv_ADDR, mnum, type, p1, p2, p3)
    }

    if (MICOS_MTNSRV["default_port"] == 0)
        MICOS_MTNSRV["default_port"] = 6542

    str = micos_mtnsrv_ADDR
    ntok = split(str, aux, ":")
    if ((ntok < 2) || (ntok > 3)) {
        printf("Micos MtnSrv: invalid ADDR specifier: %s\n", str)
        printf("  Must has the form host:[port]:controller\n")
        return ".error."
    }    
    host = aux[0]
    port = (ntok == 3) ? aux[1] : MICOS_MTNSRV["default_port"]
    socket = sprintf("%s:%s", host, port)
    ctrl = aux[ntok - 1]
    MICOS_MTNSRV[str]["ctrl"] = ctrl

    if (type == "ctrl") {
        unit = p1
        if (unit <= MICOS_MTNSRV["last_unit"])
            MICOS_MTNSRV["all_hosts"] = " "
        MICOS_MTNSRV["last_unit"] = unit

        allhosts = MICOS_MTNSRV["all_hosts"]
        str = sprintf(" %s ", socket)
        if (index(allhosts, str) == 0) {
            ret = micos_mtnsrv_host_config(host, socket)
            if (ret < 0)
                return ".error."
            MICOS_MTNSRV["all_hosts"] = sprintf("%s%s ", allhosts, socket)
        }

        ret = micos_mtnsrv_ctrl_config(host, ctrl)
    } else {
        ret = micos_mtnsrv_motor_config(ctrl, mnum, p1, p2, p3)
    }

    if (ret < 0)
        return ".error."
}'

def micos_mtnsrv_host_config(host, socket) '{
    global MICOS_MTNSRV[]
    local varr str i allctrls ctrl key 

    MICOS_MTNSRV[host]["socket"] = socket
    MICOS_MTNSRV[host]["srv_ready"] = 0

    if (!sock_par(socket, "connect")) {
        print "Micos MtnSrv: error connecting to", socket
        return -1
    }

    micos_mtnsrv_flush(socket)
    sock_par(socket, "timeout", 2)

    varr = micos_mtnsrv_talk(socket, "Version", 1)
    if (((whatis("varr") & 0x01000000) == 0) || (varr["nr"] < 2)) {
        print "Micos MtnSrv: error getting server Version:", socket
        return -1
    }
    printf("%s %son %s: ", varr[0], varr[1], socket)

    str = micos_mtnsrv_status(socket)
    if ((str <= 0) || (str == "")) {
        print "Micos MtnSrv: error getting server Version:", socket
        return -1
    }
    printf("Server %s\n", str)

    MICOS_MTNSRV[host]["srv_ready"] = 1

    clist = micos_mtnsrv_ctrl_list(socket)
    allctrls = " "
    for (i = 0; i < clist["nr"]; i++) {
        ctrl = clist[i]
        allctrls = sprintf("%s%s ", allctrls, ctrl)
        MICOS_MTNSRV[ctrl]["host"] = host
        MICOS_MTNSRV[ctrl]["ctrl_ready"] = 0
    }
    MICOS_MTNSRV[host]["all_ctrls"] = allctrls

    return 0
}'

def micos_mtnsrv_host_socket(host) '{
    return MICOS_MTNSRV[host]["socket"]
}'

def micos_mtnsrv_ctrl_config(host, ctrl) '{
    global MICOS_MTNSRV[]
    local str socket alist[] i allaxes mot

    socket = micos_mtnsrv_host_socket(host)

    str = sprintf(" %s ", ctrl)
    if (index(MICOS_MTNSRV[host]["all_ctrls"], str) == 0) {
        printf("Micos MtnSrv: controller %s is not defined on %s\n", \
	       ctrl, socket)
        return -1
    }

    MICOS_MTNSRV[ctrl]["ctrl_ready"] = micos_mtnsrv_ctrl_ready(socket, ctrl)

    alist = micos_mtnsrv_ctrl_axes(socket, ctrl)
    allaxes = " "
    for (i = 0; i < alist["nr"]; i++) {
        mot = alist[i]
        MICOS_MTNSRV[mot]["ctrl"] = ctrl
        MICOS_MTNSRV[mot]["mne"] = ""
        MICOS_MTNSRV[mot]["idx"] = i
        allaxes = sprintf("%s%s ", allaxes, mot)
    }
    MICOS_MTNSRV[ctrl]["nr_axes"] = alist["nr"]
    MICOS_MTNSRV[ctrl]["all_axes"] = allaxes

    MICOS_MTNSRV["error_str"] = MICOS_MTNSRV["error_cmd"] = ""
    cdef("user_pollmove", "micos_mtnsrv_check_error(); ", "micos")
    return 0
}'

def micos_mtnsrv_ctrl_socket(ctrl) '{
    return micos_mtnsrv_host_socket(MICOS_MTNSRV[ctrl]["host"])
}'


def micos_mtnsrv_motor_config(ctrl, mnum, unit, module, channel) '{
    global MICOS_MTNSRV[]
    local mot mne mstr str host mctrl socket ready retry

    mne = motor_mne(mnum)
    mot = motor_par(mnum, "misc_par_1")
    MICOS_MTNSRV[mne]["motor"] = ""

    mstr = sprintf("Generic Par. 1 of SPEC motor %s", mne)
    mstr = sprintf("Micos MtnSrv: motor \"%s\" (%s)", mot, mstr)

    host = MICOS_MTNSRV[ctrl]["host"]
    socket = micos_mtnsrv_host_socket(host)
    if (!MICOS_MTNSRV[host]["srv_ready"]) {
        printf("Micos MtnSrv: server on %s is not available\n", socket)
        return -1
    }

    mctrl = MICOS_MTNSRV[mot]["ctrl"]
    if (mctrl == 0) {
        printf("%s not found\n", mstr)
        return -1
    } else if (mctrl != ctrl) {
        printf("%s has ctrl. %s, not %s\n", mstr, mctrl, ctrl)
        return -1
    }

    str = sprintf(" %s ", mot)
    if (index(MICOS_MTNSRV[ctrl]["all_axes"], str) == 0) {
        printf("%s not found in ctrl %s\n", mstr, ctrl)
        return -1
    }

    if (!MICOS_MTNSRV[ctrl]["ctrl_ready"]) {
        printf("Activating controller %s at %s ...\n", ctrl, host)
        if (micos_mtnsrv_ctrl_power(socket, ctrl, 1) < 0)
            return -1
    }
    ready = micos_mtnsrv_ctrl_ready(socket, ctrl)
    for (retry = 0; (retry < 10) && !ready; retry++) {
	sleep(1)
        ready = micos_mtnsrv_ctrl_ready(socket, ctrl)
    }
    MICOS_MTNSRV[ctrl]["ctrl_ready"] = ready
    if (!ready) {
        printf("Micos MtnSrv: could not activate controller %s\n", ctrl)
        return -1
    }

    MICOS_MTNSRV[mot]["mne"] = mne
    MICOS_MTNSRV[mot]["in_calib"] = 0
    MICOS_MTNSRV[mne]["motor"] = mot
    MICOS_MTNSRV[mot]["step_size"] = motor_par(mnum, "step_size")

    MICOS_MTNSRV[mot]["ustep_size"] = 0
    MICOS_MTNSRV[mot]["ustep_accel"] = 0
    MICOS_MTNSRV[mot]["ustep_prev_accel"] = 0
    
    return 0
}'

def micos_mtnsrv_motor_socket(mne) '{
    return micos_mtnsrv_ctrl_socket(MICOS_MTNSRV[mne]["ctrl"])
}'

def micos_mtnsrv_cmd(mnum, cmd, p1, p2) '{
    global MICOS_MTNSRV[]
    local host mne mot ctrl ret

    if (MICOS_MTNSRV["debug"])
        printf("micos_mtnsrv_cmd: ADDR=%s, mnum=%s, cmd=%s, p1=%s, p2=%s\n", \
               micos_mtnsrv_ADDR, mnum, cmd, p1, p2)

    ctrl = MICOS_MTNSRV[micos_mtnsrv_ADDR]["ctrl"]
    host = MICOS_MTNSRV[ctrl]["host"]
    if (!MICOS_MTNSRV[host]["srv_ready"] || !MICOS_MTNSRV[ctrl]["ctrl_ready"])
        return 0

    if (mnum == "..") {
        ret = micos_mtnsrv_unit_cmd(ctrl, cmd, p1, p2)
    } else {
        mot = micos_mtnsrv_motor_from_mne(motor_mne(mnum))
        if (mot < 0)
            return 0

        ret = micos_mtnsrv_motor_cmd(ctrl, mot, cmd, p1, p2)
    }

    return ret
}'

def micos_mtnsrv_motor_from_mne(mne) '{
    local mot

    mot = MICOS_MTNSRV[mne]["motor"]
    return ((mot == 0) || (mot == "")) ? -1 : mot
}'

def micos_mtnsrv_unit_cmd(ctrl, cmd, p1, p2) '{
    local socket allpos i str pos

    socket = micos_mtnsrv_ctrl_socket(ctrl)
    if (cmd == "flush_all") {
        return micos_mtnsrv_flush(socket)
    } else if (cmd == "preread_all") {
        allpos = micos_mtnsrv_ctrl_allpos(socket, ctrl)
        for (i = 0; i < allpos["nr"]; i++)
            MICOS_MTNSRV[ctrl][sprintf("pos_%d", i)] = allpos[i]
    } else if (cmd == "prestart_all") {
        MICOS_MTNSRV[ctrl]["moving_mot"] = " "
    } else if (cmd == "start_all") {
        str = "MoveAbs"
        for (i = 0; i < MICOS_MTNSRV[ctrl]["nr_axes"]; i++) {
            pos = MICOS_MTNSRV[ctrl][sprintf("pos_%d", i)]
            str = sprintf("%s %g", str, pos)
        }
        micos_mtnsrv_ctrl_talk(socket, ctrl, str)
    } else if (cmd == "abort_all") {
        micos_mtnsrv_ctrl_stop(socket, ctrl)
    }
    return 0
}'

def micos_mtnsrv_motor_cmd(ctrl, mot, cmd, p1, p2) '{
    local socket idx movingmot wasmoving ctrlready poskey allpos str 
    local speed speed_err

    socket = micos_mtnsrv_ctrl_socket(ctrl)
    idx = MICOS_MTNSRV[mot]["idx"]
    poskey = sprintf("pos_%d", idx)
    movingmot = MICOS_MTNSRV[ctrl]["moving_mot"]

    if (cmd == "get_status") {
        str = sprintf(" %s ", mot)
        wasmoving = (index(movingmot, str) > 0)
        ctrlready = micos_mtnsrv_ctrl_ready(socket, ctrl)
        if (wasmoving && !ctrlready)
            return 0x02
        if (wasmoving && ctrlready)
            MICOS_MTNSRV[ctrl]["moving_mot"] = " "
        return 0
    } else if (cmd == "preread_one") {
        allpos = micos_mtnsrv_ctrl_allpos(socket, ctrl)
        MICOS_MTNSRV[ctrl][poskey] = allpos[idx]
    } else if (cmd == "position") {
        if (MICOS_MTNSRV[mot]["in_calib"])
            return MICOS_MTNSRV[mot]["pre_calib_pos"]
        return MICOS_MTNSRV[ctrl][poskey]
    } else if (cmd == "start_one") {
        MICOS_MTNSRV[ctrl]["moving_mot"] = sprintf("%s%s ", movingmot, mot)
        MICOS_MTNSRV[ctrl][poskey] = p1
    } else if (cmd == "search") {
        if (!MICOS_MTNSRV[mot]["just_sync"]) {
            if (p1 == "lim-") {
                micos_mtnsrv_motor_par(ctrl, mot, "calib_add")
                micos_mtnsrv_motor_par(ctrl, mot, "calib_start")
            } else if (substr(p1, 1, 4) == "home") {
                micos_mtnsrv_motor_par(ctrl, mot, "ref_move_add")
                micos_mtnsrv_motor_par(ctrl, mot, "ref_move_start")
            }
	}
	MICOS_MTNSRV[mot]["just_sync"] = 0
        MICOS_MTNSRV[mot]["in_calib"] = 0
    } else if (cmd == "slew_rate") {
        speed = p1 / MICOS_MTNSRV[mot]["step_size"]
	micos_mtnsrv_motor_set_speed(socket, ctrl, idx, speed)
	speed_err = micos_mtnsrv_motor_get_speed(socket, ctrl, idx) - speed
	if (fabs(speed_err) > (0.005 * fabs(speed))) {
            printf("Error setting MICOS MtnSrv %s mot. %s speed to %s\n", \
                   ctrl, mot, speed)
            return -1
        }
    }

    return 0
}'

def micos_mtnsrv_par(mnum, cmd, dir, p1, p2) '{
    local ctrl host mot 

    if (MICOS_MTNSRV["debug"]) {
        printf("micos_mtnsrv_par: ")
        printf("ADDR=%s, mnum=%s, cmd=%s, dir=%s, p1=%s, p2=%s\n", \
               micos_mtnsrv_ADDR, mnum, cmd, dir, p1, p2)
    }

    ctrl = MICOS_MTNSRV[micos_mtnsrv_ADDR]["ctrl"]
    host = MICOS_MTNSRV[ctrl]["host"]
    if (!MICOS_MTNSRV[host]["srv_ready"] || !MICOS_MTNSRV[ctrl]["ctrl_ready"])
        return 0
    mot = micos_mtnsrv_motor_from_mne(motor_mne(mnum))
    if (mot < 0) 
        return 0

    return micos_mtnsrv_motor_par(ctrl, mot, cmd, dir, p1, p2)
}'

def micos_mtnsrv_motor_par(ctrl, mot, cmd, dir, p1, p2) '{
    local idx val socket axesidx allaxes axesarr[] nraxes mne auxmot key pos i

    socket = micos_mtnsrv_ctrl_socket(ctrl)
    idx = MICOS_MTNSRV[mot]["idx"]
    key = (index(cmd, "calib") > 0) ? "calib_mot" : "ref_move_mot"

    if (cmd == "reset_pos") {
        val = micos_mtnsrv_ctrl_reset_pos(socket, ctrl)
    } else if (cmd == "kill") {
        val = micos_mtnsrv_ctrl_kill(socket, ctrl)
    } else if ((cmd == "calib_add") || (cmd == "ref_move_add")) {
        allaxes = MICOS_MTNSRV[ctrl][key]
        if (allaxes == 0)
            allaxes = " "
        if (index(allaxes, sprintf(" %s ", mot)) == 0)
            MICOS_MTNSRV[ctrl][key] = sprintf("%s%s ", allaxes, mot)
    } else if ((cmd == "calib_start") || (cmd == "ref_move_start")) {
        allaxes = MICOS_MTNSRV[ctrl][key]
        axesidx = ""
        nraxes = split(allaxes, axesarr)
        micos_mtnsrv_unit_cmd(ctrl, "preread_all")
        for (i = 0; i < nraxes; i++) {
            auxmot = axesarr[i]
            val = MICOS_MTNSRV[ctrl]["moving_mot"]
            MICOS_MTNSRV[ctrl]["moving_mot"] = sprintf("%s%s ", val, auxmot)
            val = MICOS_MTNSRV[auxmot]["idx"]
            pos = MICOS_MTNSRV[ctrl][sprintf("pos_%d", val)]
            MICOS_MTNSRV[auxmot]["pre_calib_pos"] = pos
            MICOS_MTNSRV[auxmot]["in_calib"] = 1
            axesidx = sprintf("%s %d", axesidx, val + 1)
        }
        MICOS_MTNSRV[ctrl][key] = 0

        if (cmd == "ref_move_start")
            val = micos_mtnsrv_ctrl_ref_move(socket, ctrl, axesidx)
        else
            val = micos_mtnsrv_ctrl_calib(socket, ctrl, axesidx)
    } else if ((cmd == "calib_finished") || (cmd == "ref_move_finished")) {
        val = micos_mtnsrv_ctrl_ready(socket, ctrl)
    } else if (cmd == "just_sync") {
        MICOS_MTNSRV[mot]["just_sync"] = 1
    } else if (substr(cmd, 1, 5) == "talk ") {
        val = micos_mtnsrv_talk(socket, substr(cmd, 6))
    }

    return val
}'

def micosmtnsrvcalib '{
    local motstr

    motstr = ($# > 0) ? "$*" : getval("Enter the motors to calibrate", "")
    if (motstr != "")
        micos_mtnsrv_ctrl_calib_sync(motstr)
}'

def micosmtnsrvrefmove '{
    local motstr

    motstr = ($# > 0) ? "$*" : getval("Enter the motors to move to ref.", "")
    if (motstr != "")
        micos_mtnsrv_ctrl_ref_move_sync(motstr)
}'

def micos_mtnsrv_motor_get_speed(socket, ctrl, mot_idx) '{
    local allspeeds
    allspeeds = micos_mtnsrv_ctrl_all_speeds(socket, ctrl)
    return allspeeds[mot_idx]
}'

def micos_mtnsrv_motor_set_speed(socket, ctrl, mot_idx, speed) '{
    local cmd
    cmd = sprintf("Speed %d %g", mot_idx + 1, speed)
    return micos_mtnsrv_ctrl_cmd(socket, ctrl, cmd)
}'

def micos_mtnsrv_ctrl_calib_sync(motstr) '{
    return micos_mtnsrv_ctrl_sync(motstr, "calib")
}'

def micos_mtnsrv_ctrl_ref_move_sync(motstr) '{
    return micos_mtnsrv_ctrl_sync(motstr, "ref_move")
}'

# op: "calib" or "ref_move"
def micos_mtnsrv_ctrl_sync(motstr, op) '{
    local nrmot motarr[] i mnum cmd

    nrmot = split(motstr, motarr)
    if (nrmot == 1) {
        cmd = (op == "calib") ? "lim-" : "home"
        chg_dial(motor_num(motarr[0]), cmd)
        micos_mtnsrv_ctrl_wait_ready(motstr)
	return 0
    }
    
    for (i = 0; i < nrmot; i++) {
        mnum = motor_num(motarr[i])
        motor_par(mnum, sprintf("%s_add", op))
    }

    motor_par(mnum, sprintf("%s_start", op))
    while (!motor_par(mnum, sprintf("%s_finished", op)))
        sleep(0.1)

    for (i = 0; i < nrmot; i++) {
        mnum = motor_num(motarr[i])
	motor_par(mnum, "just_sync")
        cmd = (op == "calib") ? "lim-" : "home"
        chg_dial(mnum, cmd)
    }

    return 0    
}'

def micos_mtnsrv_ctrl_wait_ready(motstr) '{
    local nrmot motarr[] i mot ctrl socket

    nrmot = split(motstr, motarr)
    for (i = 0; i < nrmot; i++) {
        mot = MICOS_MTNSRV[motarr[i]]["motor"]
        ctrl = MICOS_MTNSRV[mot]["ctrl"]
        socket = micos_mtnsrv_ctrl_socket(ctrl)
        while (!micos_mtnsrv_ctrl_ready(socket, ctrl))
            sleep(0.1)
    }
}'

def micos_mtnsrv_ctrl_kill(socket, ctrl) '{
    return micos_mtnsrv_talk(socket, sprintf("%s Kill", ctrl), 2)
}'

def micos_mtnsrv_ctrl_reset_pos(socket, ctrl) '{
    return micos_mtnsrv_talk(socket, sprintf("%s ResetPos", ctrl), 2)
}'

def micos_mtnsrv_ctrl_ref_move(socket, ctrl, axes) '{
    return micos_mtnsrv_ctrl_talk(socket, ctrl, sprintf("RefMove %s", axes), \
					        "RefMove")
}'

def micos_mtnsrv_ctrl_calib(socket, ctrl, axes) '{
    return micos_mtnsrv_ctrl_talk(socket, ctrl, sprintf("Calibrate %s", axes),\
						"Calibration")
}'

def micos_mtnsrv_ctrl_all_speeds(socket, ctrl) '{
    local allspeed speedarr[] aux i aux[]
    allspeed = micos_mtnsrv_ctrl_talk(socket, ctrl, "Speed ?", "Speed")
    speedarr["nr"] = split(allspeed, aux)
    for (i = 0; i < speedarr["nr"]; i++)
        speedarr[i] = aux[i] + 0

    return speedarr
}'

def micos_mtnsrv_ctrl_stop(socket, ctrl) '{
    return micos_mtnsrv_ctrl_cmd(socket, ctrl, "Stop")
}'

def micos_mtnsrv_ctrl_allpos(socket, ctrl) '{
    local allpos aux[] i posarr[]

    allpos = micos_mtnsrv_ctrl_talk(socket, ctrl, "Crds ?", "Crds")
    posarr["nr"] = split(allpos, aux)
    for (i = 0; i < posarr["nr"]; i++)
        posarr[i] = aux[i] + 0

    return posarr
}'

def micos_mtnsrv_ctrl_power(socket, ctrl, poweron) '{
    local status setcmd good changing

    good = poweron ? "on" : "off"
    status = micos_mtnsrv_ctrl_power_status(socket, ctrl) 
    if (status == good)
        return 0

    changing = "starting"
    setcmd = sprintf("Power %s", good)
    micos_mtnsrv_ctrl_talk(socket, ctrl, setcmd, "Power")
    status = micos_mtnsrv_ctrl_power_status(socket, ctrl) 
    while (status == changing) {
	sleep(0.2)
        status = micos_mtnsrv_ctrl_power_status(socket, ctrl) 
    }
    if (status != good)
        printf("Micos MtnSrv: could not set controller %s power %s\n", \
		ctrl, good)

    return (status == good) ? 0 : -1
}'

def micos_mtnsrv_ctrl_power_status(socket, ctrl) '{
    return micos_mtnsrv_ctrl_talk(socket, ctrl, "Power ?", "Power")
}'

def micos_mtnsrv_ctrl_ready(socket, ctrl) '{
    return (micos_mtnsrv_ctrl_talk(socket, ctrl, "IsReady") == "ready")
}'

def micos_mtnsrv_ctrl_axes(socket, ctrl) '{
    return micos_mtnsrv_list_get(socket, sprintf("%s ListAxes", ctrl), \
					 "AxisName")
}'

def micos_mtnsrv_ctrl_list(socket) '{
    return micos_mtnsrv_list_get(socket, "List Controllers", "Controller") 
}'

def micos_mtnsrv_status(socket) '{
    return micos_mtnsrv_talk(socket, "Server Status", "Server ")
}'

def micos_mtnsrv_check_error() '{
    if (MICOS_MTNSRV["error_str"] != "") {
        print "MICOS MtnSrv: Error detected. Aborting!!"
        MICOS_MTNSRV["error_str"] = MICOS_MTNSRV["error_cmd"] = ""
        stop()
        exit
    }

}'

def micos_mtnsrv_list_get(socket, cmd, prefix, ignorefirst) '{

    local mlist[] mkey line aux[] first

    mlist = micos_mtnsrv_talk(socket, cmd, 1)
    for (mkey = 0; mkey < mlist["nr"]; mkey++) {
        line = mlist[mkey]
        if (prefix)
            micos_mtnsrv_check_resp(line, prefix)
        split(line, aux, ": ")
        mlist[mkey] = aux[1]
    }
    if (ignorefirst)
        micos_mtnsrv_del_first_line(mlist)

    return mlist
}'

def micos_mtnsrv_ctrl_cmd(socket, ctrl, cmd) '{
    return micos_mtnsrv_talk(socket, sprintf("%s %s", ctrl, cmd), 2)
}'

def micos_mtnsrv_ctrl_talk(socket, ctrl, cmd, resp) '{
    local ctrl_resp
    ctrl_resp = sprintf("%s %s", ctrl, resp ? sprintf("%s ", resp) : "")
    return micos_mtnsrv_talk(socket, sprintf("%s %s", ctrl, cmd), ctrl_resp)
}'

# mode:   0=wr+rd(single) 1=wr+read(multi) 2=wr 
#       str=wr+rd(single, check+strip str)
def micos_mtnsrv_talk(socket, line, mode) '{
    local ret resp rline multiline

    ret = micos_mtnsrv_write(socket, line)
    if ((ret < 0) || (mode == 2))
	return ret

    multiline = (mode == 1)
    resp["nr"] = 0
    if (multiline) {
        resp = micos_mtnsrv_read(socket, multiline)
        rline = resp[0]
    } else
        rline = micos_mtnsrv_read(socket, multiline)

    if (index(rline, "Warning") > 0) {
	printf("\nMICOS MtnSrv: %s\n[Cmd sent: %s]\n", rline, line)
        MICOS_MTNSRV["error_cmd"] = line
        MICOS_MTNSRV["error_str"] = rline
        if (multiline)
	    micos_mtnsrv_del_first_line(resp)
	else
            rline = micos_mtnsrv_read(socket, multiline)
    }

    if (multiline)
        return resp
    else if (mode == 0)
        return rline

    return micos_mtnsrv_check_resp(rline, mode)
}'

def micos_mtnsrv_check_resp(resp, prefix, nostrip) '{
    if (index(resp, prefix) != 1) {
        printf("Error: MICOS MtnSrv resp. \"%s\" does not start in \"%s\"\n", \
	       resp, prefix)
        return -1
    }    
    return !nostrip ? substr(resp, length(prefix) + 1) : resp
}'

def micos_mtnsrv_del_first_line(resp) '{
    local i

    for (i = 0; i < resp["nr"] - 1; i++)
        resp[i] = resp[i + 1]
    delete resp[i]
    resp["nr"]--
}'

def micos_mtnsrv_write(socket, line) '{
   return sock_put(socket, sprintf("%s\r\n", line))
}'

def micos_mtnsrv_read(socket, multiline) '{
   local line str llist[] nlines

   str = ""
   while (((line = sock_get(socket, "\r\n")) != "") && multiline)
       str = sprintf("%s%s", str, line)

   nlines = split(multiline ? str : line, llist, "\r\n") - 1
   delete llist[nlines]
   llist["nr"] = nlines
   if (multiline)
       return llist
   return llist[0]
}'

def micos_mtnsrv_flush(socket) '{
   sock_par(socket, "flush")
   return 0
}'

#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR% A.Homs / BLISS / ESRF (2007)