1 module hitgvoip;
2 
3 import c.hitgvoip;
4 import std.file;
5 import std.outbuffer;
6 import std.string;
7 import core.stdc.string;
8 import std.json;
9 import std.conv;
10 import std.exception;
11 public import c.hitgvoip: CallProtocols;
12 public import c.hitgvoip: AUDIO_STATE;
13 public import c.hitgvoip: CALL_STATE;
14 public import c.hitgvoip: PROXY_PROTOCOL;
15 public import c.hitgvoip: NET_TYPE;
16 public import c.hitgvoip: DATA_SAVING;
17 public import c.hitgvoip: CallDiscardReason = call_discard_reason_t;
18 public import c.hitgvoip: CallStats = call_stats_t;
19 public import c.hitgvoip: VoipConfig = config_t;
20 public import c.hitgvoip: VoipEndpoint = endpoints_t;
21 public import c.hitgvoip: VoipProxy = proxy_t;
22 
23 class HiTGVoip {
24 	private bool isCreator;
25 	private long otherID;
26 	private long callID;
27 	private CALL_STATE callState;
28 	private CallProtocols callProtocols;
29 	private DiscardCallback discardCallback;
30 	private AcceptCallback acceptCallback;
31 	private client_t client;
32 	
33 	
34 	this() {
35 	}
36 	
37 	this(bool isCreator, long otherID, long callID, CALL_STATE callState, CallProtocols callProtocols) {
38 		this.isCreator = isCreator;
39 		this.otherID = otherID;
40 		this.callID = callID;
41 		this.callState = callState;
42 		this.callProtocols = callProtocols;
43 	}
44 	
45 	this(bool isCreator, long otherID, long callID, CALL_STATE callState, CallProtocols callProtocols, DiscardCallback discardCallback, AcceptCallback acceptCallback) {
46 		this.isCreator = isCreator;
47 		this.otherID = otherID;
48 		this.callID = callID;
49 		this.callState = callState;
50 		this.callProtocols = callProtocols;
51 		this.discardCallback = discardCallback;
52 		this.acceptCallback = acceptCallback;
53 	}
54 	
55 	~this() {
56 		destroy_client(this.client);
57 	}
58 
59 	HiTGVoip setIsCreator(bool isCreator) {
60 		this.isCreator = isCreator;
61 		return this;
62 	}
63 
64 	HiTGVoip setOtherID(long otherID) {
65 		this.otherID = otherID;
66 		return this;
67 	}
68 
69 	HiTGVoip setCallID(long callID) {
70 		this.callID = callID;
71 		return this;
72 	}
73 
74 	HiTGVoip setCallState(CALL_STATE callState) {
75 		this.callState = callState;
76 		return this;
77 	}
78 
79 	HiTGVoip setCallProtocols(CallProtocols callProtocols) {
80 		this.callProtocols = callProtocols;
81 		return this;
82 	}
83 
84 	HiTGVoip setDiscardCallback(DiscardCallback discardCallback) {
85 		this.discardCallback = discardCallback;
86 		return this;
87 	}
88 
89 	HiTGVoip setAcceptCallback(AcceptCallback acceptCallback) {
90 		this.acceptCallback = acceptCallback;
91 		return this;
92 	}
93 	
94 	void init() {
95 		call_params_t callParams = {this.isCreator, 
96 			this.otherID, 
97 			this.callID, 
98 			this.callState, 
99 			this.callProtocols, 
100 			this.discardCallback, 
101 			this.acceptCallback};
102 		this.client = create_client(callParams);
103 	}
104 	
105 	void discard(CallDiscardReason discardReason, int rating) {
106 		discard_call(this.client, discardReason, rating);
107 	}
108 	
109 	void accept() {
110 		accept_call(this.client);
111 	}
112 	
113 	void close() {
114 		destroy_client(this.client);
115 	}
116 	
117 	void start() {
118 		c.hitgvoip.start(this.client);
119 	}
120 	
121 	long whenCreated() {
122 		return when_created(this.client);
123 	}
124 	
125 	bool isCallCreator() {
126 		return to!bool(is_creator(this.client));
127 	}
128 	
129 	long getOtherID() {
130 		return get_other_ID(this.client);
131 	}
132 	
133 	CallProtocols getCallProtocol() {
134 		return get_protocol(this.client);
135 	}
136 	
137 	long getCallID() {
138 		return get_call_id(this.client);
139 	}
140 	
141 	HiTGVoip setOutputFile(string outputPath) {
142 		immutable(int) result = set_output_file(this.client, stringToCStr(outputPath));
143 		
144 		if(!result) {
145 			throw new FileException(outputPath.readText); 
146 		}
147 
148 		return this;
149 	}
150 	
151 	HiTGVoip play(string inputPath) {
152 		immutable(int) result = c.hitgvoip.play(this.client, stringToCStr(inputPath));
153 		
154 		if(!result) {
155 			throw new FileException(inputPath.readText); 
156 		}
157 
158 		return this;
159 	}
160 	
161 	HiTGVoip playOnHold(string[] inputPaths) {
162 		immutable(int) result = play_on_hold(this.client, stringsToArrStr(inputPaths), inputPaths.length);
163 		
164 		if(!result) {
165 			throw new FileException(join(inputPaths, ", ").readText); 
166 		}
167 
168 		return this;
169 	}
170 	
171 	HiTGVoip muteMic() {
172 		set_mic_mute(this.client, 1);
173 		return this;
174 	}
175 	
176 	HiTGVoip unmuteMic() {
177 		set_mic_mute(this.client, 0);
178 		return this;
179 	}
180 	
181 	HiTGVoip debugCtl(int request, int param) {
182 		debug_ctl(this.client, request, param);
183 		return this;
184 	}
185 	
186 	HiTGVoip setBitrate(int bitrate) {
187 		set_bitrate(this.client, bitrate);
188 		return this;
189 	}
190 	
191 	string getDebugLog() {
192 		auto buf = new OutBuffer();
193 		char[8192] buffer;
194 		
195 		while((get_debug_log(this.client, buffer.ptr, 8192)) != 0) {
196 			buf.write(buffer);
197 			buffer[] = 0;
198 		}
199 		
200 		return buf.toString();
201 	}
202 	
203 	string getVersion() {
204 		auto cversion = get_version();
205 		return cversion[0..strlen(cversion)].idup;
206 	}
207 	
208 	int getSignalBarsCount() {
209 		return get_signal_bars_count(this.client);
210 	}
211 	
212 	long getPreferredRelayID() {
213 		return get_preferred_relay_ID(this.client);
214 	}
215 	
216 	int getLastError() {
217 		return get_last_error(this.client);
218 	}
219 	
220 	string getDebugString() {
221 		auto buf = new OutBuffer();
222 		char[8192] buffer;
223 		
224 		while((get_debug_string(this.client, buffer.ptr, 8192)) != 0) {
225 			buf.write(buffer);
226 			buffer[] = 0;
227 		}
228 		
229 		return buf.toString();
230 	}
231 	
232 	CallStats getCallStats() {
233 		return get_stats(this.client);
234 	} 
235 	
236 	uint getPeerCapabilities() {
237 		return get_peer_capabilities(this.client);
238 	}
239 	
240 	HiTGVoip requestCallUpgrade() {
241 		request_call_upgrade(this.client);
242 		return this;
243 	}
244 	
245 	HiTGVoip sendGroupCallKey(string key) {
246 		send_group_call_key(this.client, stringToCStr(key));
247 		return this;
248 	}
249 	
250 	int getState() {
251 		return get_state(this.client);
252 	}
253 	
254 	bool isPlaying() {
255 		return to!bool(is_playing(this.client));
256 	}
257 	
258 	HiTGVoip setServerConfig(string jsonServerConfig) {
259 		auto json = parseJSON(jsonServerConfig);
260 		auto length = json.object.values.length + json.object.keys.length;
261 		string[] config = new string[length];
262 		int index = 0;		
263 		
264 		foreach(elem; json.object.byKeyValue()) {
265 			string key = elem.key;
266 			string value;
267 			
268 			if(json[key].type == JSONType..string) {
269 				value = json[key].str;
270 			}
271 			
272 			if(json[key].type == JSONType.integer) {
273 				value = to!string(json[key].integer);
274 			}
275 			
276 			if(json[key].type == JSONType.float_) {
277 				value = to!string(json[key].floating);
278 			}
279 			
280 			if(json[key].type == JSONType.uinteger) {
281 				value = to!string(json[key].uinteger);
282 			}
283 			
284 			if(json[key].type == JSONType.true_ || json[key].type == JSONType.false_) {
285 				value = to!string(json[key].boolean);
286 			}
287 			
288 			config[index] = key;
289 			config[++index] = value; 
290 			index++;
291 		}
292 		
293 		set_server_config(stringsToArrStr(config), to!int(length));
294 		return this;
295 	}
296 	
297 	HiTGVoip setConfig(config_t config) {
298 		set_config(this.client, config);
299 		return this;
300 	}
301 	
302 	HiTGVoip setEncryptionKey(string key) {
303 		set_encryption_key(this.client, stringToCStr(key));
304 		return this;
305 	}
306 	
307 	HiTGVoip setNetworkType(NET_TYPE type) {
308 		set_network_type(this.client, type);
309 		return this;
310 	}
311 	
312 	HiTGVoip setProxy(proxy_t proxy) {
313 		set_proxy(this.client, proxy);
314 		return this;
315 	}
316 
317 	private char* stringToCStr(string str) {
318 		auto cstr = str.toStringz;
319 		return cstr[0 .. str.length + 1].dup.ptr;
320 	}
321 
322 	private char[]* stringsToArrStr(string[] strings) {
323 		char[][] carr = new char[][strings.length];
324 
325 		foreach(i, elem; strings) {
326 			carr[i] = (toStringz(elem)[0..elem.length + 1]).dup;
327 		}
328 
329 		return carr.ptr;
330 	}
331 }