* Parses the ICE ufrag, pwd, and candidates from the SDP answer. * * This function is used to extract the ICE ufrag, pwd, and candidates from the SDP answer. * It returns an error if any of these fields is NULL. The function only uses the first * candidate if there are multiple candidates. However, support for multiple candidates * will be added in the future. * * @param s Pointer to the AV
| 921 | * @returns Returns 0 if successful or AVERROR_xxx if an error occurs. |
| 922 | */ |
| 923 | static int parse_answer(AVFormatContext *s) |
| 924 | { |
| 925 | int ret = 0; |
| 926 | AVIOContext *pb; |
| 927 | char line[MAX_URL_SIZE]; |
| 928 | const char *ptr; |
| 929 | int i; |
| 930 | WHIPContext *whip = s->priv_data; |
| 931 | |
| 932 | if (!whip->sdp_answer || !strlen(whip->sdp_answer)) { |
| 933 | av_log(whip, AV_LOG_ERROR, "No answer to parse\n"); |
| 934 | return AVERROR(EINVAL); |
| 935 | } |
| 936 | |
| 937 | pb = avio_alloc_context(whip->sdp_answer, strlen(whip->sdp_answer), 0, NULL, NULL, NULL, NULL); |
| 938 | if (!pb) |
| 939 | return AVERROR(ENOMEM); |
| 940 | |
| 941 | for (i = 0; !avio_feof(pb); i++) { |
| 942 | ff_get_chomp_line(pb, line, sizeof(line)); |
| 943 | if (av_strstart(line, "a=ice-lite", &ptr)) |
| 944 | whip->is_peer_ice_lite = 1; |
| 945 | if (av_strstart(line, "a=ice-ufrag:", &ptr) && !whip->ice_ufrag_remote) { |
| 946 | whip->ice_ufrag_remote = av_strdup(ptr); |
| 947 | if (!whip->ice_ufrag_remote) { |
| 948 | ret = AVERROR(ENOMEM); |
| 949 | goto end; |
| 950 | } |
| 951 | } else if (av_strstart(line, "a=ice-pwd:", &ptr) && !whip->ice_pwd_remote) { |
| 952 | whip->ice_pwd_remote = av_strdup(ptr); |
| 953 | if (!whip->ice_pwd_remote) { |
| 954 | ret = AVERROR(ENOMEM); |
| 955 | goto end; |
| 956 | } |
| 957 | } else if (av_strstart(line, "a=fingerprint:", &ptr) && !whip->remote_fingerprint) { |
| 958 | /* SDP a=fingerprint format is "<algo> <hex:hex:...>". Skip |
| 959 | * the algo token, store the hex string for post-handshake compare. */ |
| 960 | const char *space = strchr(ptr, ' '); |
| 961 | if (space) { |
| 962 | whip->remote_fingerprint = av_strdup(space + 1); |
| 963 | if (!whip->remote_fingerprint) { |
| 964 | ret = AVERROR(ENOMEM); |
| 965 | goto end; |
| 966 | } |
| 967 | } |
| 968 | } else if (av_strstart(line, "a=candidate:", &ptr) && !whip->ice_protocol) { |
| 969 | if (ptr && av_stristr(ptr, "host")) { |
| 970 | /* Refer to RFC 5245 15.1 */ |
| 971 | char foundation[33], protocol[17], host[129]; |
| 972 | int component_id, priority, port; |
| 973 | ret = sscanf(ptr, "%32s %d %16s %d %128s %d typ host", foundation, &component_id, protocol, &priority, host, &port); |
| 974 | if (ret != 6) { |
| 975 | av_log(whip, AV_LOG_ERROR, "Failed %d to parse line %d %s from %s\n", |
| 976 | ret, i, line, whip->sdp_answer); |
| 977 | ret = AVERROR(EIO); |
| 978 | goto end; |
| 979 | } |
| 980 |
no test coverage detected