webrtc-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,169 @@
1
+ #ifndef WEBRTC_RUBY_H
2
+ #define WEBRTC_RUBY_H
3
+
4
+ #include <stdint.h>
5
+ #include <stdbool.h>
6
+ #include <stddef.h>
7
+
8
+ #ifdef __cplusplus
9
+ extern "C" {
10
+ #endif
11
+
12
+ #ifdef _WIN32
13
+ #ifdef WEBRTC_RUBY_BUILDING
14
+ #define WEBRTC_RUBY_API __declspec(dllexport)
15
+ #else
16
+ #define WEBRTC_RUBY_API __declspec(dllimport)
17
+ #endif
18
+ #else
19
+ #define WEBRTC_RUBY_API __attribute__((visibility("default")))
20
+ #endif
21
+
22
+ typedef struct webrtc_peer_connection* webrtc_peer_connection_t;
23
+ typedef struct webrtc_data_channel* webrtc_data_channel_t;
24
+ typedef struct webrtc_session_description* webrtc_session_description_t;
25
+ typedef struct webrtc_ice_candidate* webrtc_ice_candidate_t;
26
+
27
+ typedef struct {
28
+ int code;
29
+ const char* message;
30
+ } webrtc_error_t;
31
+
32
+ typedef struct {
33
+ const char** ice_servers;
34
+ size_t ice_servers_count;
35
+ const char* ice_transport_policy;
36
+ const char* bundle_policy;
37
+ } webrtc_configuration_t;
38
+
39
+ typedef void (*webrtc_void_callback)(void* user_data);
40
+ typedef void (*webrtc_ice_candidate_callback)(const char* candidate,
41
+ const char* sdp_mid,
42
+ int sdp_mline_index,
43
+ void* user_data);
44
+ typedef void (*webrtc_data_channel_callback)(webrtc_data_channel_t dc,
45
+ void* user_data);
46
+ typedef void (*webrtc_message_callback)(const uint8_t* data,
47
+ size_t length,
48
+ bool is_binary,
49
+ void* user_data);
50
+ typedef void (*webrtc_state_change_callback)(int state, void* user_data);
51
+
52
+ WEBRTC_RUBY_API int webrtc_init(void);
53
+ WEBRTC_RUBY_API void webrtc_cleanup(void);
54
+
55
+ WEBRTC_RUBY_API webrtc_peer_connection_t webrtc_peer_connection_create(
56
+ const webrtc_configuration_t* config,
57
+ webrtc_error_t* error);
58
+ WEBRTC_RUBY_API void webrtc_peer_connection_destroy(webrtc_peer_connection_t pc);
59
+
60
+ WEBRTC_RUBY_API int webrtc_peer_connection_create_offer(
61
+ webrtc_peer_connection_t pc,
62
+ webrtc_session_description_t* out_sdp,
63
+ webrtc_error_t* error);
64
+
65
+ WEBRTC_RUBY_API int webrtc_peer_connection_create_answer(
66
+ webrtc_peer_connection_t pc,
67
+ webrtc_session_description_t* out_sdp,
68
+ webrtc_error_t* error);
69
+
70
+ WEBRTC_RUBY_API int webrtc_peer_connection_set_local_description(
71
+ webrtc_peer_connection_t pc,
72
+ webrtc_session_description_t sdp,
73
+ webrtc_error_t* error);
74
+
75
+ WEBRTC_RUBY_API int webrtc_peer_connection_set_remote_description(
76
+ webrtc_peer_connection_t pc,
77
+ webrtc_session_description_t sdp,
78
+ webrtc_error_t* error);
79
+
80
+ WEBRTC_RUBY_API int webrtc_peer_connection_add_ice_candidate(
81
+ webrtc_peer_connection_t pc,
82
+ webrtc_ice_candidate_t candidate,
83
+ webrtc_error_t* error);
84
+
85
+ WEBRTC_RUBY_API void webrtc_peer_connection_on_ice_candidate(
86
+ webrtc_peer_connection_t pc,
87
+ webrtc_ice_candidate_callback callback,
88
+ void* user_data);
89
+
90
+ WEBRTC_RUBY_API void webrtc_peer_connection_on_connection_state_change(
91
+ webrtc_peer_connection_t pc,
92
+ webrtc_state_change_callback callback,
93
+ void* user_data);
94
+
95
+ WEBRTC_RUBY_API void webrtc_peer_connection_on_data_channel(
96
+ webrtc_peer_connection_t pc,
97
+ webrtc_data_channel_callback callback,
98
+ void* user_data);
99
+
100
+ WEBRTC_RUBY_API int webrtc_peer_connection_get_signaling_state(
101
+ webrtc_peer_connection_t pc);
102
+ WEBRTC_RUBY_API int webrtc_peer_connection_get_ice_gathering_state(
103
+ webrtc_peer_connection_t pc);
104
+ WEBRTC_RUBY_API int webrtc_peer_connection_get_ice_connection_state(
105
+ webrtc_peer_connection_t pc);
106
+ WEBRTC_RUBY_API int webrtc_peer_connection_get_connection_state(
107
+ webrtc_peer_connection_t pc);
108
+
109
+ WEBRTC_RUBY_API webrtc_data_channel_t webrtc_peer_connection_create_data_channel(
110
+ webrtc_peer_connection_t pc,
111
+ const char* label,
112
+ bool ordered,
113
+ int max_retransmits,
114
+ int max_packet_life_time,
115
+ const char* protocol,
116
+ bool negotiated,
117
+ int id,
118
+ webrtc_error_t* error);
119
+
120
+ WEBRTC_RUBY_API void webrtc_data_channel_destroy(webrtc_data_channel_t dc);
121
+ WEBRTC_RUBY_API int webrtc_data_channel_send(webrtc_data_channel_t dc,
122
+ const uint8_t* data,
123
+ size_t length,
124
+ bool is_binary,
125
+ webrtc_error_t* error);
126
+ WEBRTC_RUBY_API void webrtc_data_channel_close(webrtc_data_channel_t dc);
127
+ WEBRTC_RUBY_API int webrtc_data_channel_get_ready_state(webrtc_data_channel_t dc);
128
+ WEBRTC_RUBY_API const char* webrtc_data_channel_get_label(webrtc_data_channel_t dc);
129
+ WEBRTC_RUBY_API size_t webrtc_data_channel_get_buffered_amount(webrtc_data_channel_t dc);
130
+
131
+ WEBRTC_RUBY_API void webrtc_data_channel_on_open(webrtc_data_channel_t dc,
132
+ webrtc_void_callback callback,
133
+ void* user_data);
134
+ WEBRTC_RUBY_API void webrtc_data_channel_on_message(webrtc_data_channel_t dc,
135
+ webrtc_message_callback callback,
136
+ void* user_data);
137
+ WEBRTC_RUBY_API void webrtc_data_channel_on_close(webrtc_data_channel_t dc,
138
+ webrtc_void_callback callback,
139
+ void* user_data);
140
+
141
+ WEBRTC_RUBY_API webrtc_session_description_t webrtc_session_description_create(
142
+ const char* type,
143
+ const char* sdp,
144
+ webrtc_error_t* error);
145
+ WEBRTC_RUBY_API void webrtc_session_description_destroy(
146
+ webrtc_session_description_t sd);
147
+ WEBRTC_RUBY_API const char* webrtc_session_description_get_type(
148
+ webrtc_session_description_t sd);
149
+ WEBRTC_RUBY_API const char* webrtc_session_description_get_sdp(
150
+ webrtc_session_description_t sd);
151
+
152
+ WEBRTC_RUBY_API webrtc_ice_candidate_t webrtc_ice_candidate_create(
153
+ const char* candidate,
154
+ const char* sdp_mid,
155
+ int sdp_mline_index,
156
+ webrtc_error_t* error);
157
+ WEBRTC_RUBY_API void webrtc_ice_candidate_destroy(webrtc_ice_candidate_t ic);
158
+ WEBRTC_RUBY_API const char* webrtc_ice_candidate_get_candidate(
159
+ webrtc_ice_candidate_t ic);
160
+ WEBRTC_RUBY_API const char* webrtc_ice_candidate_get_sdp_mid(
161
+ webrtc_ice_candidate_t ic);
162
+ WEBRTC_RUBY_API int webrtc_ice_candidate_get_sdp_mline_index(
163
+ webrtc_ice_candidate_t ic);
164
+
165
+ #ifdef __cplusplus
166
+ }
167
+ #endif
168
+
169
+ #endif
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebRTC
4
+ class RTCConfiguration
5
+ ICE_TRANSPORT_POLICIES = %i[all relay].freeze
6
+ BUNDLE_POLICIES = %i[balanced max_compat max_bundle].freeze
7
+ RTCP_MUX_POLICIES = %i[require].freeze
8
+
9
+ attr_accessor :ice_servers, :ice_transport_policy, :bundle_policy, :rtcp_mux_policy, :certificates,
10
+ :ice_candidate_pool_size
11
+
12
+ def initialize(options = {})
13
+ @ice_servers = normalize_ice_servers(options[:ice_servers] || options[:iceServers] || [])
14
+ @ice_transport_policy = options[:ice_transport_policy] || options[:iceTransportPolicy] || :all
15
+ @bundle_policy = options[:bundle_policy] || options[:bundlePolicy] || :balanced
16
+ @rtcp_mux_policy = options[:rtcp_mux_policy] || options[:rtcpMuxPolicy] || :require
17
+ @certificates = options[:certificates] || []
18
+ @ice_candidate_pool_size = options[:ice_candidate_pool_size] || options[:iceCandidatePoolSize] || 0
19
+
20
+ validate!
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ iceServers: @ice_servers.map(&:to_h),
26
+ iceTransportPolicy: @ice_transport_policy,
27
+ bundlePolicy: @bundle_policy,
28
+ rtcpMuxPolicy: @rtcp_mux_policy,
29
+ iceCandidatePoolSize: @ice_candidate_pool_size
30
+ }
31
+ end
32
+
33
+ private
34
+
35
+ def normalize_ice_servers(servers)
36
+ servers.map do |server|
37
+ server.is_a?(RTCIceServer) ? server : RTCIceServer.new(server)
38
+ end
39
+ end
40
+
41
+ def validate!
42
+ unless ICE_TRANSPORT_POLICIES.include?(@ice_transport_policy)
43
+ raise InvalidParameterError, "Invalid ice_transport_policy: #{@ice_transport_policy}"
44
+ end
45
+
46
+ unless BUNDLE_POLICIES.include?(@bundle_policy)
47
+ raise InvalidParameterError, "Invalid bundle_policy: #{@bundle_policy}"
48
+ end
49
+
50
+ return if @ice_candidate_pool_size.between?(0, 255)
51
+
52
+ raise InvalidParameterError, 'ice_candidate_pool_size must be 0-255'
53
+ end
54
+ end
55
+
56
+ class RTCIceServer
57
+ attr_accessor :urls, :username, :credential, :credential_type
58
+
59
+ def initialize(options = {})
60
+ @urls = normalize_urls(options[:urls] || options[:url])
61
+ @username = options[:username]
62
+ @credential = options[:credential]
63
+ @credential_type = options[:credential_type] || options[:credentialType] || :password
64
+
65
+ validate!
66
+ end
67
+
68
+ def to_h
69
+ hash = { urls: @urls }
70
+ hash[:username] = @username if @username
71
+ hash[:credential] = @credential if @credential
72
+ hash[:credentialType] = @credential_type if @credential
73
+ hash
74
+ end
75
+
76
+ private
77
+
78
+ def normalize_urls(urls)
79
+ case urls
80
+ when String
81
+ [urls]
82
+ when Array
83
+ urls
84
+ else
85
+ []
86
+ end
87
+ end
88
+
89
+ def validate!
90
+ raise InvalidParameterError, 'ICE server URLs required' if @urls.empty?
91
+
92
+ @urls.each do |url|
93
+ unless url.start_with?('stun:', 'stuns:', 'turn:', 'turns:')
94
+ raise InvalidParameterError, "Invalid ICE server URL: #{url}"
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebRTC
4
+ class RTCDataChannel
5
+ READY_STATES = %i[connecting open closing closed].freeze
6
+ BINARY_TYPES = %i[blob arraybuffer].freeze
7
+
8
+ attr_reader :label, :ordered, :max_packet_life_time, :max_retransmits, :protocol, :negotiated, :id
9
+ attr_accessor :buffered_amount_low_threshold, :binary_type
10
+
11
+ def initialize(ptr, options = {})
12
+ @ptr = ptr
13
+ @callbacks = {}
14
+ @binary_type = :arraybuffer
15
+ @buffered_amount_low_threshold = 0
16
+
17
+ @label = options[:label] || FFI.webrtc_data_channel_get_label(ptr)
18
+ @ordered = options.fetch(:ordered, true)
19
+ @max_packet_life_time = options[:max_packet_life_time]
20
+ @max_retransmits = options[:max_retransmits]
21
+ @protocol = options[:protocol] || ''
22
+ @negotiated = options.fetch(:negotiated, false)
23
+ @id = options[:id]
24
+ end
25
+
26
+ def ready_state
27
+ return :closed if @ptr.nil?
28
+
29
+ state_index = FFI.webrtc_data_channel_get_ready_state(@ptr)
30
+ READY_STATES[state_index] || :unknown
31
+ end
32
+
33
+ def buffered_amount
34
+ return 0 if @ptr.nil?
35
+
36
+ FFI.webrtc_data_channel_get_buffered_amount(@ptr)
37
+ end
38
+
39
+ def send(data)
40
+ raise InvalidStateError, 'DataChannel is not open' unless ready_state == :open
41
+
42
+ is_binary = data.is_a?(String) && data.encoding == Encoding::BINARY
43
+ send_data(data, is_binary)
44
+ end
45
+
46
+ def send_text(data)
47
+ raise InvalidStateError, 'DataChannel is not open' unless ready_state == :open
48
+
49
+ send_data(data.to_s, false)
50
+ end
51
+
52
+ def send_binary(data)
53
+ raise InvalidStateError, 'DataChannel is not open' unless ready_state == :open
54
+
55
+ send_data(data, true)
56
+ end
57
+
58
+ def close
59
+ return if @ptr.nil?
60
+
61
+ FFI.webrtc_data_channel_close(@ptr)
62
+ end
63
+
64
+ def destroy
65
+ return if @ptr.nil?
66
+
67
+ FFI.webrtc_data_channel_destroy(@ptr)
68
+ @ptr = nil
69
+ end
70
+
71
+ def on_open(&block)
72
+ @callbacks[:open] = block
73
+ setup_open_callback
74
+ end
75
+
76
+ def on_close(&block)
77
+ @callbacks[:close] = block
78
+ setup_close_callback
79
+ end
80
+
81
+ def on_error(&block)
82
+ @callbacks[:error] = block
83
+ end
84
+
85
+ def on_message(&block)
86
+ @callbacks[:message] = block
87
+ setup_message_callback
88
+ end
89
+
90
+ def on_buffered_amount_low(&block)
91
+ @callbacks[:buffered_amount_low] = block
92
+ end
93
+
94
+ private
95
+
96
+ def send_data(data, is_binary)
97
+ data_str = data.to_s
98
+ ptr = ::FFI::MemoryPointer.from_string(data_str)
99
+ error = FFI::Error.new
100
+
101
+ result = FFI.webrtc_data_channel_send(@ptr, ptr, data_str.bytesize, is_binary, error)
102
+ raise OperationError, error[:message] if result != 0
103
+
104
+ data_str.bytesize
105
+ end
106
+
107
+ def setup_open_callback
108
+ callback = proc do |_user_data|
109
+ @callbacks[:open]&.call
110
+ end
111
+ @callbacks[:open_proc] = callback
112
+ FFI.webrtc_data_channel_on_open(@ptr, callback, ::FFI::Pointer::NULL)
113
+ end
114
+
115
+ def setup_close_callback
116
+ callback = proc do |_user_data|
117
+ @callbacks[:close]&.call
118
+ end
119
+ @callbacks[:close_proc] = callback
120
+ FFI.webrtc_data_channel_on_close(@ptr, callback, ::FFI::Pointer::NULL)
121
+ end
122
+
123
+ def setup_message_callback
124
+ callback = proc do |data_ptr, length, is_binary, _user_data|
125
+ data = data_ptr.read_bytes(length)
126
+ data = data.force_encoding(Encoding::UTF_8) unless is_binary
127
+
128
+ message = MessageEvent.new(data, is_binary)
129
+ @callbacks[:message]&.call(message)
130
+ end
131
+ @callbacks[:message_proc] = callback
132
+ FFI.webrtc_data_channel_on_message(@ptr, callback, ::FFI::Pointer::NULL)
133
+ end
134
+ end
135
+
136
+ class MessageEvent
137
+ attr_reader :data, :origin, :last_event_id
138
+
139
+ def initialize(data, is_binary)
140
+ @data = data
141
+ @is_binary = is_binary
142
+ @origin = ''
143
+ @last_event_id = ''
144
+ end
145
+
146
+ def binary?
147
+ @is_binary
148
+ end
149
+
150
+ def text?
151
+ !@is_binary
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebRTC
4
+ class RTCDtlsTransport
5
+ STATES = %i[new connecting connected closed failed].freeze
6
+
7
+ attr_reader :ice_transport, :state
8
+
9
+ def initialize(options = {})
10
+ @ice_transport = options[:ice_transport] || RTCIceTransport.new
11
+ @state = :new
12
+ @remote_certificates = []
13
+ @callbacks = {}
14
+ @ptr = options[:ptr]
15
+ end
16
+
17
+ def get_remote_certificates
18
+ @remote_certificates.dup
19
+ end
20
+
21
+ def on_state_change(&block)
22
+ @callbacks[:state_change] = block
23
+ end
24
+
25
+ def on_error(&block)
26
+ @callbacks[:error] = block
27
+ end
28
+
29
+ private
30
+
31
+ def set_state(new_state)
32
+ return if @state == new_state
33
+
34
+ @state = new_state
35
+ @callbacks[:state_change]&.call
36
+ end
37
+ end
38
+
39
+ class RTCDtlsFingerprint
40
+ attr_reader :algorithm, :value
41
+
42
+ def initialize(algorithm:, value:)
43
+ @algorithm = algorithm
44
+ @value = value
45
+ end
46
+
47
+ def to_h
48
+ {
49
+ algorithm: @algorithm,
50
+ value: @value
51
+ }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebRTC
4
+ class RTCDTMFSender
5
+ VALID_TONES = '0123456789ABCD*#,'
6
+
7
+ attr_reader :tone_buffer, :duration, :inter_tone_gap
8
+
9
+ def initialize(options = {})
10
+ @sender = options[:sender]
11
+ @tone_buffer = ''
12
+ @duration = 100
13
+ @inter_tone_gap = 70
14
+ @callbacks = {}
15
+ end
16
+
17
+ def can_insert_dtmf?
18
+ @sender&.track&.kind == :audio
19
+ end
20
+
21
+ def insert_dtmf(tones, duration: 100, inter_tone_gap: 70)
22
+ raise InvalidStateError, 'Cannot insert DTMF' unless can_insert_dtmf?
23
+
24
+ validate_tones!(tones)
25
+ validate_duration!(duration)
26
+ validate_inter_tone_gap!(inter_tone_gap)
27
+
28
+ @duration = duration
29
+ @inter_tone_gap = inter_tone_gap
30
+ @tone_buffer = tones.upcase
31
+
32
+ schedule_tone_playback
33
+ end
34
+
35
+ def on_tone_change(&block)
36
+ @callbacks[:tone_change] = block
37
+ end
38
+
39
+ private
40
+
41
+ def validate_tones!(tones)
42
+ tones.each_char do |char|
43
+ raise InvalidParameterError, "Invalid DTMF tone: #{char}" unless VALID_TONES.include?(char.upcase)
44
+ end
45
+ end
46
+
47
+ def validate_duration!(duration)
48
+ return if duration >= 40 && duration <= 6000
49
+
50
+ raise InvalidParameterError, 'Duration must be between 40 and 6000 ms'
51
+ end
52
+
53
+ def validate_inter_tone_gap!(gap)
54
+ return if gap >= 30
55
+
56
+ raise InvalidParameterError, 'Inter-tone gap must be at least 30 ms'
57
+ end
58
+
59
+ def schedule_tone_playback
60
+ return if @tone_buffer.empty?
61
+
62
+ tone = @tone_buffer[0]
63
+ @tone_buffer = @tone_buffer[1..]
64
+
65
+ emit_tone_change(tone)
66
+ end
67
+
68
+ def emit_tone_change(tone)
69
+ event = RTCDTMFToneChangeEvent.new(tone: tone)
70
+ @callbacks[:tone_change]&.call(event)
71
+ end
72
+ end
73
+
74
+ class RTCDTMFToneChangeEvent
75
+ attr_reader :tone
76
+
77
+ def initialize(tone:)
78
+ @tone = tone
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebRTC
4
+ class Error < StandardError; end
5
+
6
+ class InitializationError < Error; end
7
+ class OperationError < Error; end
8
+ class InvalidStateError < Error; end
9
+ class InvalidParameterError < Error; end
10
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module WebRTC
6
+ module FFI
7
+ extend ::FFI::Library
8
+
9
+ LIB_NAME = case RbConfig::CONFIG['host_os']
10
+ when /darwin/ then 'libwebrtc_ruby.dylib'
11
+ when /mswin|mingw/ then 'webrtc_ruby.dll'
12
+ else 'libwebrtc_ruby.so'
13
+ end
14
+
15
+ LIB_PATH = File.join(__dir__, '..', '..', '..', 'ext', 'webrtc_ruby', 'build', LIB_NAME)
16
+
17
+ ffi_lib LIB_PATH if File.exist?(LIB_PATH)
18
+
19
+ class Error < ::FFI::Struct
20
+ layout :code, :int,
21
+ :message, :string
22
+ end
23
+
24
+ class Configuration < ::FFI::Struct
25
+ layout :ice_servers, :pointer,
26
+ :ice_servers_count, :size_t,
27
+ :ice_transport_policy, :pointer,
28
+ :bundle_policy, :pointer
29
+ end
30
+
31
+ callback :void_callback, [:pointer], :void
32
+ callback :ice_candidate_callback, %i[string string int pointer], :void
33
+ callback :data_channel_callback, %i[pointer pointer], :void
34
+ callback :message_callback, %i[pointer size_t bool pointer], :void
35
+ callback :state_change_callback, %i[int pointer], :void
36
+
37
+ attach_function :webrtc_init, [], :int
38
+ attach_function :webrtc_cleanup, [], :void
39
+
40
+ attach_function :webrtc_peer_connection_create,
41
+ [Configuration.by_ref, Error.by_ref], :pointer
42
+ attach_function :webrtc_peer_connection_destroy, [:pointer], :void
43
+
44
+ attach_function :webrtc_peer_connection_create_offer,
45
+ [:pointer, :pointer, Error.by_ref], :int
46
+ attach_function :webrtc_peer_connection_create_answer,
47
+ [:pointer, :pointer, Error.by_ref], :int
48
+
49
+ attach_function :webrtc_peer_connection_set_local_description,
50
+ [:pointer, :pointer, Error.by_ref], :int
51
+ attach_function :webrtc_peer_connection_set_remote_description,
52
+ [:pointer, :pointer, Error.by_ref], :int
53
+ attach_function :webrtc_peer_connection_add_ice_candidate,
54
+ [:pointer, :pointer, Error.by_ref], :int
55
+
56
+ attach_function :webrtc_peer_connection_on_ice_candidate,
57
+ %i[pointer ice_candidate_callback pointer], :void
58
+ attach_function :webrtc_peer_connection_on_connection_state_change,
59
+ %i[pointer state_change_callback pointer], :void
60
+ attach_function :webrtc_peer_connection_on_data_channel,
61
+ %i[pointer data_channel_callback pointer], :void
62
+
63
+ attach_function :webrtc_peer_connection_get_signaling_state, [:pointer], :int
64
+ attach_function :webrtc_peer_connection_get_ice_gathering_state, [:pointer], :int
65
+ attach_function :webrtc_peer_connection_get_ice_connection_state, [:pointer], :int
66
+ attach_function :webrtc_peer_connection_get_connection_state, [:pointer], :int
67
+
68
+ attach_function :webrtc_peer_connection_create_data_channel,
69
+ [:pointer, :string, :bool, :int, :int, :string, :bool, :int, Error.by_ref],
70
+ :pointer
71
+
72
+ attach_function :webrtc_data_channel_destroy, [:pointer], :void
73
+ attach_function :webrtc_data_channel_send,
74
+ [:pointer, :pointer, :size_t, :bool, Error.by_ref], :int
75
+ attach_function :webrtc_data_channel_close, [:pointer], :void
76
+ attach_function :webrtc_data_channel_get_ready_state, [:pointer], :int
77
+ attach_function :webrtc_data_channel_get_label, [:pointer], :string
78
+ attach_function :webrtc_data_channel_get_buffered_amount, [:pointer], :size_t
79
+
80
+ attach_function :webrtc_data_channel_on_open,
81
+ %i[pointer void_callback pointer], :void
82
+ attach_function :webrtc_data_channel_on_message,
83
+ %i[pointer message_callback pointer], :void
84
+ attach_function :webrtc_data_channel_on_close,
85
+ %i[pointer void_callback pointer], :void
86
+
87
+ attach_function :webrtc_session_description_create,
88
+ [:string, :string, Error.by_ref], :pointer
89
+ attach_function :webrtc_session_description_destroy, [:pointer], :void
90
+ attach_function :webrtc_session_description_get_type, [:pointer], :string
91
+ attach_function :webrtc_session_description_get_sdp, [:pointer], :string
92
+
93
+ attach_function :webrtc_ice_candidate_create,
94
+ [:string, :string, :int, Error.by_ref], :pointer
95
+ attach_function :webrtc_ice_candidate_destroy, [:pointer], :void
96
+ attach_function :webrtc_ice_candidate_get_candidate, [:pointer], :string
97
+ attach_function :webrtc_ice_candidate_get_sdp_mid, [:pointer], :string
98
+ attach_function :webrtc_ice_candidate_get_sdp_mline_index, [:pointer], :int
99
+ end
100
+ end