diff options
Diffstat (limited to 'example/main.c')
-rw-r--r-- | example/main.c | 220 |
1 files changed, 111 insertions, 109 deletions
diff --git a/example/main.c b/example/main.c index e850a40..77b68da 100644 --- a/example/main.c +++ b/example/main.c @@ -12,126 +12,128 @@ // Helper function for parsing JSON static bool matches(const char *json, jsmntok_t *tok, const char *s) { - if (JSMN_STRING != tok->type) return false; - if (strlen(s) != tok->end - tok->start) return false; - return 0 == strncmp(json + tok->start, s, tok->end - tok->start); + if (JSMN_STRING != tok->type) return false; + if (strlen(s) != tok->end - tok->start) return false; + return 0 == strncmp(json + tok->start, s, tok->end - tok->start); } // Parses ICE candidate from stringified JSON struct trtc_ice_candidate_t parse_ice_candidate(const char *s) { - struct trtc_ice_candidate_t c = { 0 }; - - int i, r; - jsmn_parser p; - jsmntok_t t[16]; - jsmn_init(&p); - - r = jsmn_parse(&p, s, strlen(s), t, sizeof(t) / sizeof(t[0])); - if (r < 0) { - printf("%s:%d: failed to parse json", __func__, __LINE__); - return c; - } - - if (r < 1 || t[0].type != JSMN_OBJECT) { - printf("%s:%d: object expected", __func__, __LINE__); - return c; - } - - for (i = 1; i < r; i++) { - if (matches(s, &t[i], "candidate")) { - strncpy(c.candidate, s + t[i + 1].start, - t[i + 1].end - t[i + 1].start); - i++; - } else if (matches(s, &t[i], "sdpMid")) { - strncpy(c.sdp_mid, s + t[i + 1].start, - t[i + 1].end - t[i + 1].start); - i++; - } else if (matches(s, &t[i], "sdpMLineIndex")) { - c.sdp_mline_index = atoi(s + t[i + 1].start); - i++; - } else if (matches(s, &t[i], "usernameFragment")) { - strncpy(c.username_fragment, s + t[i + 1].start, - t[i + 1].end - t[i + 1].start); - i++; - } - } - - return c; + struct trtc_ice_candidate_t c = { 0 }; + + int i, r; + jsmn_parser p; + jsmntok_t t[16]; + jsmn_init(&p); + + r = jsmn_parse(&p, s, strlen(s), t, sizeof(t) / sizeof(t[0])); + if (r < 0) { + printf("%s:%d: failed to parse json", __func__, __LINE__); + return c; + } + + if (r < 1 || t[0].type != JSMN_OBJECT) { + printf("%s:%d: object expected", __func__, __LINE__); + return c; + } + + for (i = 1; i < r; i++) { + if (matches(s, &t[i], "candidate")) { + strncpy(c.candidate, s + t[i + 1].start, + t[i + 1].end - t[i + 1].start); + i++; + } else if (matches(s, &t[i], "sdpMid")) { + strncpy(c.sdp_mid, s + t[i + 1].start, + t[i + 1].end - t[i + 1].start); + i++; + } else if (matches(s, &t[i], "sdpMLineIndex")) { + c.sdp_mline_index = atoi(s + t[i + 1].start); + i++; + } else if (matches(s, &t[i], "usernameFragment")) { + strncpy(c.username_fragment, s + t[i + 1].start, + t[i + 1].end - t[i + 1].start); + i++; + } + } + + return c; } // (callback) Called for each discovered local ICE candidate void on_ice_candidate(const struct trtc_ice_candidate_t c, void *arg) { - // send ice candidate over signaling channel - printf("{" - "\"candidate\":\"%s\"," - "\"sdpMLineIndex\":%d," - "\"sdpMid\":\"%s\"," - "\"usernameFragment\":null" - "}\n", c.candidate, c.sdp_mline_index, c.sdp_mid); + // send ice candidate over signaling channel + printf("{" + "\"candidate\":\"%s\"," + "\"sdpMLineIndex\":%d," + "\"sdpMid\":\"%s\"," + "\"usernameFragment\":null" + "}\n", c.candidate, c.sdp_mline_index, c.sdp_mid); } int main(int argc, char **argv) { - openlog(NULL, LOG_PERROR, LOG_USER); - - // disable stdout buffering to ensure signaling messages send immediately - setvbuf(stdout, NULL, _IONBF, 0); - - // initialize tinyrtc library - trtc_init(); - - // create peer connection - struct trtc_config_t cfg = { - .ice_servers = { - { - .urls = { - "stun:stun.liburtc.org", - }, - } - } - }; - struct trtc_peerconn_t* pc = trtc_peer_connection(cfg); - if (!pc) { - syslog(LOG_ERR, "trtc_peer_connection() failed"); - return -1; - } - - trtc_set_on_ice_candidate(pc, on_ice_candidate, NULL); - - while (true) { - int n; - char *msg = NULL; - size_t msglen = 0; - - - if (n = getline(&msg, &msglen, stdin), -1 == n) { - syslog(LOG_ERR, "%m"); - return -1; - } - - // case: sdp offer - if (strstr(msg, "\"sdp\"")) { - // XXX trtc_set_remote_description(pc, offer); - const char *answer = trtc_create_answer(pc); - - /* send SDP answer via stdout signaling channel */ - printf("{\"sdp\":\"%s\",\"type\":\"answer\"}\n", answer); - - trtc_set_local_description(pc, answer); - - // case: ice candidate - } else if (strstr(msg, "\"candidate\"")) { - struct trtc_ice_candidate_t c = parse_ice_candidate(msg); - trtc_add_ice_candidate(pc, c); - - // case: error - } else { - printf("unrecognized signaling message\n"); - } - } - - syslog(LOG_ERR, "terminating"); - - return 0; + openlog(NULL, LOG_PERROR, LOG_USER); + + // disable stdout buffering to ensure signaling messages send immediately + setvbuf(stdout, NULL, _IONBF, 0); + + // initialize tinyrtc library + trtc_init(); + + // create peer connection + struct trtc_config_t cfg = { + .ice_servers = { + { + .urls = { + "stun:stun.liburtc.org", + }, + } + } + }; + struct trtc_peerconn_t* pc = trtc_peer_connection(cfg); + if (!pc) { + syslog(LOG_ERR, "trtc_peer_connection() failed"); + return -1; + } + + trtc_set_on_ice_candidate(pc, on_ice_candidate, NULL); + + while (true) { + int n; + char *msg = NULL; + size_t msglen = 0; + + + if (n = getline(&msg, &msglen, stdin), -1 == n) { + syslog(LOG_ERR, "%m"); + return -1; + } + + // case: sdp offer + if (strstr(msg, "\"sdp\"")) { + // XXX trtc_set_remote_description(pc, offer); + const char *answer = trtc_create_answer(pc); + + /* send SDP answer via stdout signaling channel */ + printf("{\"sdp\":\"%s\",\"type\":\"answer\"}\n", answer); + + trtc_set_local_description(pc, answer); + + // case: ice candidate + } else if (strstr(msg, "\"candidate\"")) { + struct trtc_ice_candidate_t c = parse_ice_candidate(msg); + trtc_add_ice_candidate(pc, c); + + // case: error + } else { + printf("unrecognized signaling message\n"); + } + } + + syslog(LOG_ERR, "terminating"); + + return 0; } + +/* vim: set et ts=4 sw=4 : */ |