| 1237 | } |
| 1238 | |
| 1239 | static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock, |
| 1240 | FAR struct msghdr *msg, int flags) |
| 1241 | { |
| 1242 | FAR struct rpmsg_socket_conn_s *conn = psock->s_conn; |
| 1243 | FAR struct sockaddr *from = msg->msg_name; |
| 1244 | FAR socklen_t *fromlen = &msg->msg_namelen; |
| 1245 | FAR void *buf = msg->msg_iov->iov_base; |
| 1246 | size_t len = msg->msg_iov->iov_len; |
| 1247 | ssize_t ret; |
| 1248 | |
| 1249 | if (msg->msg_iovlen != 1) |
| 1250 | { |
| 1251 | return -ENOTSUP; |
| 1252 | } |
| 1253 | |
| 1254 | if (psock->s_type != SOCK_STREAM && |
| 1255 | _SS_ISBOUND(conn->sconn.s_flags) && |
| 1256 | !_SS_ISCONNECTED(conn->sconn.s_flags)) |
| 1257 | { |
| 1258 | ret = rpmsg_socket_connect_internal(psock); |
| 1259 | if (ret < 0) |
| 1260 | { |
| 1261 | return ret; |
| 1262 | } |
| 1263 | } |
| 1264 | |
| 1265 | if (!_SS_ISCONNECTED(conn->sconn.s_flags)) |
| 1266 | { |
| 1267 | return -EISCONN; |
| 1268 | } |
| 1269 | |
| 1270 | if (conn->how & SHUT_RD) |
| 1271 | { |
| 1272 | return 0; |
| 1273 | } |
| 1274 | |
| 1275 | nxmutex_lock(&conn->recvlock); |
| 1276 | if (psock->s_type != SOCK_STREAM) |
| 1277 | { |
| 1278 | uint32_t datalen; |
| 1279 | |
| 1280 | ret = circbuf_read(&conn->recvbuf, &datalen, sizeof(uint32_t)); |
| 1281 | if (ret > 0) |
| 1282 | { |
| 1283 | ret = circbuf_read(&conn->recvbuf, buf, MIN(datalen, len)); |
| 1284 | if (ret > 0 && datalen > ret) |
| 1285 | { |
| 1286 | circbuf_skip(&conn->recvbuf, datalen - ret); |
| 1287 | } |
| 1288 | |
| 1289 | conn->recvpos += datalen + sizeof(uint32_t); |
| 1290 | } |
| 1291 | } |
| 1292 | else |
| 1293 | { |
| 1294 | ret = circbuf_read(&conn->recvbuf, buf, len); |
| 1295 | conn->recvpos += ret > 0 ? ret : 0; |
| 1296 | } |
nothing calls this directly
no test coverage detected