void handle_stat(queue_t *q, mblk_t *mp) { struct ctrl_args *ctrl_args; struct ctrl_device *ctrlfd; minor_t minor; int sum; unsigned char *buf; if ((mp->b_cont = allocb(MAXPRINTBUF, BPRI_MED)) == NULL) { printf("handle_ctrl: out of message blocks\n"); qreply(q, mp); return; } buf = DB_BASE(mp->b_cont); sum = rpc_statistics(buf, buf + MAXPRINTBUF); sum += int_statistics(buf + sum, buf + MAXPRINTBUF); sum += flip_netstat(buf + sum, buf + MAXPRINTBUF); sum += ffstatistics(buf + sum, buf + MAXPRINTBUF); sum += fleth_stat(buf + sum, buf + MAXPRINTBUF); mp->b_cont->b_rptr = DB_BASE(mp->b_cont); mp->b_cont->b_wptr = mp->b_cont->b_rptr + sum; ctrl_args = (struct ctrl_args *) DB_BASE(mp); ctrl_args->ctrl_status = sum; mp->b_rptr = DB_BASE(mp); mp->b_wptr = mp->b_rptr + sizeof(struct ctrl_args); DB_TYPE(mp) = M_PROTO; qreply(q, mp); }
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog, FAR void *reply, size_t resplen) { int error; /* Get the next RPC reply from the socket */ error = rpcclnt_receive(rpc, rpc->rc_name, procid, prog, reply, resplen); if (error != 0) { fdbg("ERROR: rpcclnt_receive returned: %d\n", error); /* If we failed because of a timeout, then try sending the CALL * message again. */ if (error == EAGAIN || error == ETIMEDOUT) { rpc->rc_timeout = true; } } /* Get the xid and check that it is an RPC replysvr */ else { FAR struct rpc_reply_header *replyheader = (FAR struct rpc_reply_header *)reply; if (replyheader->rp_direction != rpc_reply) { fdbg("ERROR: Different RPC REPLY returned\n"); rpc_statistics(rpcinvalid); error = EPROTO; } } return error; }
int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog, int version, FAR void *request, size_t reqlen, FAR void *response, size_t resplen) { struct rpc_reply_header *replymsg; uint32_t tmp; uint32_t xid; int retries; int error = 0; /* Get a new (non-zero) xid */ xid = rpcclnt_newxid(); /* Initialize the RPC header fields */ rpcclnt_fmtheader((FAR struct rpc_call_header *)request, xid, prog, version, procnum); /* Get the full size of the message (the size of variable data plus the size of * the messages header). */ reqlen += sizeof(struct rpc_call_header); /* Send the RPC call messsages and receive the RPC response. A limited * number of re-tries will be attempted, but only for the case of response * timeouts. */ retries = 0; do { /* Do the client side RPC. */ rpc_statistics(rpcrequests); rpc->rc_timeout = false; /* Send the RPC CALL message */ error = rpcclnt_send(rpc, procnum, prog, request, reqlen); if (error != OK) { fvdbg("ERROR rpcclnt_send failed: %d\n", error); } /* Wait for the reply from our send */ else { error = rpcclnt_reply(rpc, procnum, prog, response, resplen); if (error != OK) { fvdbg("ERROR rpcclnt_reply failed: %d\n", error); } } retries++; } while (rpc->rc_timeout && retries <= rpc->rc_retry); if (error != OK) { fdbg("ERROR: RPC failed: %d\n", error); return error; } /* Break down the RPC header and check if it is OK */ replymsg = (FAR struct rpc_reply_header *)response; tmp = fxdr_unsigned(uint32_t, replymsg->type); if (tmp == RPC_MSGDENIED) { tmp = fxdr_unsigned(uint32_t, replymsg->status); switch (tmp) { case RPC_MISMATCH: fdbg("RPC_MSGDENIED: RPC_MISMATCH error\n"); return EOPNOTSUPP; case RPC_AUTHERR: fdbg("RPC_MSGDENIED: RPC_AUTHERR error\n"); return EACCES; default: return EOPNOTSUPP; } } else if (tmp != RPC_MSGACCEPTED) { return EOPNOTSUPP; } tmp = fxdr_unsigned(uint32_t, replymsg->status); if (tmp == RPC_SUCCESS) { fvdbg("RPC_SUCCESS\n"); } else if (tmp == RPC_PROGMISMATCH) { fdbg("RPC_MSGACCEPTED: RPC_PROGMISMATCH error\n"); return EOPNOTSUPP; } else if (tmp > 5) { fdbg("ERROR: Other RPC type: %d\n", tmp); return EOPNOTSUPP; } return OK; }