/// The next JSON-RPC request id.
$.JsonRpcClient.prototype._current_id = 1;
+
+ $.JsonRpcClient.prototype.speedTest = function (bytes, cb) {
+ var socket = this.options.getSocket(this.wsOnMessage);
+ if (socket !== null) {
+ this.speedCB = cb;
+ this.speedBytes = bytes;
+ socket.send("#SPU");
+ socket.send("#SPB\n" + new Array(bytes).join("."));
+ }
+ };
+
+
+
/**
* @fn call
* @memberof $.JsonRpcClient
$.JsonRpcClient.prototype._wsOnMessage = function(event) {
// Check if this could be a JSON RPC message.
var response;
+
+ // Special sub proto
+ if (event.data[0] == "#" && event.data[1] == "S" && event.data[2] == "P") {
+ if (event.data[3] == "U") {
+ this.up_dur = parseInt(event.data.substring(4));
+ } else if (this.speedCB && event.data[3] == "D") {
+ this.down_dur = parseInt(event.data.substring(4));
+
+ var up_kps = (((this.speedBytes * 8) / (this.up_dur / 1000)) / 1024).toFixed(0);
+ var down_kps = (((this.speedBytes * 8) / (this.down_dur / 1000)) / 1024).toFixed(0);
+
+ console.info("Speed Test: Up: " + up_kps + " Down: " + down_kps);
+ this.speedCB(event, { upDur: this.up_dur, downDur: this.down_dur, upKPS: up_kps, downKPS: down_kps });
+ this.speedCB = null;
+ }
+
+ return;
+ }
+
+
try {
response = $.parseJSON(event.data);
<body>
<div data-role="page" id="page-login" align="center">
<div data-role="header" class="page-header">
- FreeSWITCH Verto™ Video Transcoding Demo
+ FreeSWITCH Verto™ Video Transcoding Demo
</div>
</div>
</div>
+ <div data-role="page" id="page-bwtest" align="center">
+ <div data-role="header" class="page-header">
+ FreeSWITCH Verto™ Testing Network Connection
+ </div>
+
+ <h1>Testing Network Connection</h1>
+ <img src="images/speed.gif"/>
+
+
+ </div>
+
+
<div data-role="page" id="page-incall" align="center">
<div data-role="header" id="calltitle" class="pageheader">
Verto™ IN CALL
<div data-role="page" id="page-main" align="center">
<div data-role="header" class="pageheader">
- FreeSWITCH Verto™ Video Transcoding Demo
+ FreeSWITCH Verto™ Video Transcoding Demo (<span id="bwinfo">*checking*</span>)
</div>
<br>
<center> <table width="1024" border="0">
}
</script>
-
<!--<button data-inline="true" id="showdemo" onclick="toggle_demo();">View Demo Extensions</button>-->
<button data-inline="true" id="showdevices" onclick="toggle_device();">View Device Settings</button>
<button data-inline="true"id="logoutbtn">Log Out</button>
return func?func(cache):null;}
$.FSRTC.validRes=[];resI=0;checkRes(cam,func);}
$.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true);}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);}
-console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
+console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.speedTest=function(bytes,cb){var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this.speedCB=cb;this.speedBytes=bytes;socket.send("#SPU");socket.send("#SPB\n"+new Array(bytes).join("."));}};$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
if(this.options.sessid){params.sessid=this.options.sessid;}
var request={jsonrpc:'2.0',method:method,params:params,id:this._current_id++};if(!success_cb){success_cb=function(e){console.log("Success: ",e);};}
if(!error_cb){error_cb=function(e){console.log("Error: ",e);};}
self.ws_sleep=1000;self.ws_cnt=0;if(self.options.onWSConnect){self.options.onWSConnect(self);}
var req;while((req=$.JsonRpcClient.q.pop())){self._ws_socket.send(req);}};}}
return self._ws_socket?true:false;};$.JsonRpcClient.prototype._getSocket=function(onmessage_cb){if(this.options.socketUrl===null||!("WebSocket"in window))return null;this.connectSocket(onmessage_cb);return this._ws_socket;};$.JsonRpcClient.q=[];$.JsonRpcClient.prototype._wsCall=function(socket,request,success_cb,error_cb){var request_json=$.toJSON(request);if(socket.readyState<1){self=this;$.JsonRpcClient.q.push(request_json);}else{socket.send(request_json);}
-if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}else if('error'in response&&this._ws_callbacks[response.id]){var error_cb=this._ws_callbacks[response.id].error_cb;var orig_req=this._ws_callbacks[response.id].request;if(!self.authing&&response.error.code==-32000&&self.options.login&&self.options.passwd){self.authing=true;this.call("login",{login:self.options.login,passwd:self.options.passwd,loginParams:self.options.loginParams,userVariables:self.options.userVariables},this._ws_callbacks[response.id].request_obj.method=="login"?function(e){self.authing=false;console.log("logged in");delete self._ws_callbacks[response.id];if(self.options.onWSLogin){self.options.onWSLogin(true,self);}}:function(e){self.authing=false;console.log("logged in, resending request id: "+response.id);var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send(orig_req);}
+if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;if(event.data[0]=="#"&&event.data[1]=="S"&&event.data[2]=="P"){if(event.data[3]=="U"){this.up_dur=parseInt(event.data.substring(4));}else if(this.speedCB&&event.data[3]=="D"){this.down_dur=parseInt(event.data.substring(4));var up_kps=(((this.speedBytes*8)/(this.up_dur/1000))/1024).toFixed(0);var down_kps=(((this.speedBytes*8)/(this.down_dur/1000))/1024).toFixed(0);console.info("Speed Test: Up: "+up_kps+" Down: "+down_kps);this.speedCB(event,{upDur:this.up_dur,downDur:this.down_dur,upKPS:up_kps,downKPS:down_kps});this.speedCB=null;}
+return;}
+try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}else if('error'in response&&this._ws_callbacks[response.id]){var error_cb=this._ws_callbacks[response.id].error_cb;var orig_req=this._ws_callbacks[response.id].request;if(!self.authing&&response.error.code==-32000&&self.options.login&&self.options.passwd){self.authing=true;this.call("login",{login:self.options.login,passwd:self.options.passwd,loginParams:self.options.loginParams,userVariables:self.options.userVariables},this._ws_callbacks[response.id].request_obj.method=="login"?function(e){self.authing=false;console.log("logged in");delete self._ws_callbacks[response.id];if(self.options.onWSLogin){self.options.onWSLogin(true,self);}}:function(e){self.authing=false;console.log("logged in, resending request id: "+response.id);var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send(orig_req);}
if(self.options.onWSLogin){self.options.onWSLogin(true,self);}},function(e){console.log("error logging in, request id:",response.id);delete self._ws_callbacks[response.id];error_cb(response.error,this);if(self.options.onWSLogin){self.options.onWSLogin(false,self);}});return;}
delete this._ws_callbacks[response.id];error_cb(response.error,this);return;}}}catch(err){console.log("ERROR: "+err);return;}
if(typeof this.options.onmessage==='function'){event.eventData=response;if(!event.eventData){event.eventData={};}
ringing = false;
if (success) {
- online(true);
+ vertoHandle.rpcClient.speedTest(1024 * 256, function(e, obj) {
+ //console.error("Up: " + obj.upKPS, "Down: ", obj.downKPS);
+
+ if (outgoingBandwidth === "default") {
+ outgoingBandwidth = obj.upKPS * .75;
+ }
+ if (incomingBandwidth === "default") {
+ incomingBandwidth = obj.downKPS * .75;
+ }
+
+ //console.error(outgoingBandwidth, incomingBandwidth);
+ $("#bwinfo").html("<b>Bandwidth: " + "Up: " + obj.upKPS + " Down: " + obj.downKPS + "</b>");
+ online(true);
+ goto_page("main");
+ $("input[type='radio']").checkboxradio("refresh");
+ $("input[type='checkbox']").checkboxradio("refresh");
+ });
+
/*
verto.subscribe("presence", {
handler: function(v, e) {
$("#useshare").selectmenu('refresh', true);
//$("input[type='radio']).checkboxradio({});
- $("input[type='radio']").checkboxradio("refresh");
- $("input[type='checkbox']").checkboxradio("refresh");
+
+
+ //$("input[type='radio']").checkboxradio("refresh");
+ //$("input[type='checkbox']").checkboxradio("refresh");
//console.error($("#usecamera").find(":selected").val());
//$.FSRTC.getValidRes($("#usecamera").find(":selected").val(), undefined);
function init() {
cur_call = null;
- goto_page("main");
+ goto_page("bwtest");
$("#usecamera").selectmenu({});
$("#usemic").selectmenu({});
*imgP = img;
}
+void conference_video_set_incoming_bitrate(conference_member_t *member, int kps)
+{
+ switch_core_session_message_t msg = { 0 };
+
+ msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
+ msg.numeric_arg = kps * 1024;
+ msg.from = __FILE__;
+
+ switch_core_session_receive_message(member->session, &msg);
+ member->managed_kps = kps;
+}
+
+void conference_video_set_max_incoming_bitrate_member(conference_member_t *member, int kps)
+{
+ member->max_bw_in = kps;
+ member->managed_kps = 0;
+}
+
+void conference_video_set_absolute_incoming_bitrate_member(conference_member_t *member, int kps)
+{
+ member->max_bw_in = 0;
+ member->force_bw_in = kps;
+ member->managed_kps = 0;
+ if (!conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && switch_channel_test_flag(member->channel, CF_VIDEO)) {
+ conference_video_set_incoming_bitrate(member, kps);
+ }
+}
+
+void conference_video_set_max_incoming_bitrate(conference_obj_t *conference, int kps)
+{
+ conference_member_t *imember;
+
+ switch_mutex_lock(conference->member_mutex);
+ for (imember = conference->members; imember; imember = imember->next) {
+ if (imember->channel && switch_channel_ready(imember->channel) && conference_utils_member_test_flag(imember, MFLAG_RUNNING)) {
+ conference_video_set_max_incoming_bitrate_member(imember, kps);
+ }
+ }
+ switch_mutex_unlock(conference->member_mutex);
+}
+
+void conference_video_set_absolute_incoming_bitrate(conference_obj_t *conference, int kps)
+{
+ conference_member_t *imember;
+
+ switch_mutex_lock(conference->member_mutex);
+ for (imember = conference->members; imember; imember = imember->next) {
+ if (imember->channel && switch_channel_ready(imember->channel) && conference_utils_member_test_flag(imember, MFLAG_RUNNING)) {
+ conference_video_set_absolute_incoming_bitrate_member(imember, kps);
+ }
+ }
+ switch_mutex_unlock(conference->member_mutex);
+}
+
void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_t *layer)
{
if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) {
member->managed_kps = 0;
} else if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps) {
- switch_core_session_message_t msg = { 0 };
int kps;
int w = 320;
int h = 240;
h = layer->screen_h;
}
}
-
- if (!layer || !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) || member->avatar_png_img) {
- kps = 200;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
+
+ if (member->conference->force_bw_in || member->force_bw_in) {
+ if (!(kps = member->conference->force_bw_in)) {
+ kps = member->force_bw_in;
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s setting bitrate to %dkps because it was forced.\n",
switch_channel_get_name(member->channel), kps);
} else {
- kps = switch_calc_bitrate(w, h, 2, (int)(member->conference->video_fps.fps));
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n",
- switch_channel_get_name(member->channel), kps, layer->screen_w, layer->screen_h);
- }
+ int max = 0;
- msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
- msg.numeric_arg = kps * 1024;
- msg.from = __FILE__;
+ if (!layer || !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) || member->avatar_png_img) {
+ kps = 256;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
+ switch_channel_get_name(member->channel), kps);
+ } else {
+ kps = switch_calc_bitrate(w, h, 1, (int)(member->conference->video_fps.fps));
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n",
+ switch_channel_get_name(member->channel), kps, layer->screen_w, layer->screen_h);
+ }
+
+ if (member->conference->max_bw_in) {
+ max = member->conference->max_bw_in;
+ } else {
+ max = member->max_bw_in;
+ }
+
+ if (max && kps > max) {
+ kps = max;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s overriding bitrate setting to %dkps because it was the max allowed.\n",
+ switch_channel_get_name(member->channel), kps);
+ }
+ }
- switch_core_session_receive_message(member->session, &msg);
- member->managed_kps = kps;
+ conference_video_set_incoming_bitrate(member, kps);
}
}
if (video_codec_bandwidth) {
if (!strcasecmp(video_codec_bandwidth, "auto")) {
- conference->video_codec_settings.video.bandwidth = switch_calc_bitrate(canvas_w, canvas_h, 2, (int)conference->video_fps.fps);
+ conference->video_codec_settings.video.bandwidth = switch_calc_bitrate(canvas_w, canvas_h, 1, (int)conference->video_fps.fps);
} else {
conference->video_codec_settings.video.bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth);
}
int recording_members;
uint32_t video_floor_packets;
video_layout_t *new_personal_vlayout;
+ int max_bw_in;
+ int force_bw_in;
} conference_obj_t;
/* Relationship with another member */
switch_media_flow_t video_media_flow;
mcu_canvas_t *canvas;
switch_image_t *pcanvas_img;
+ int max_bw_in;
+ int force_bw_in;
};
typedef enum {
switch_ssize_t bytes;
ws_opcode_t oc;
uint8_t *data;
-
+
bytes = ws_read_frame(&jsock->ws, &oc, &data);
-
+
if (bytes < 0) {
die("BAD READ %" SWITCH_SSIZE_T_FMT "\n", bytes);
break;
}
if (bytes) {
+ char *s = (char *) data;
+
+ if (*s == '#') {
+ char repl[80] = "", *s = (char *) data;
+ switch_time_t a, b;
+
+ if (s[1] == 'S' && s[2] == 'P') {
+
+ if (s[3] == 'U') {
+
+ a = switch_time_now();
+ bytes = ws_read_frame(&jsock->ws, &oc, &data);
+ b = switch_time_now();
+
+ if (!bytes || !data) continue;
+
+ switch_snprintf(repl, sizeof(repl), "#SPU %ld", (b - a) / 1000);
+ ws_write_frame(&jsock->ws, WSOC_TEXT, repl, strlen(repl));
+
+
+ s = (char *) data;
+ s[3] = 'B';
+ a = switch_time_now();
+ ws_write_frame(&jsock->ws, WSOC_TEXT, data, bytes);
+ b = switch_time_now();
+
+ switch_snprintf(repl, sizeof(repl), "#SPD %ld", (b - a) / 1000);
+ ws_write_frame(&jsock->ws, WSOC_TEXT, repl, strlen(repl));
+ }
+ }
+
+ continue;
+ }
+
+
if (process_input(jsock, data, bytes) != SWITCH_STATUS_SUCCESS) {
die("Input Error\n");
}
}
}
- if (bytes > sizeof(wsh->buffer) -1) {
+ if (bytes > wsh->buflen -1) {
goto err;
}
}
}
- } while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 100);
+ } while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 1000);
goto end;
}
ms_sleep(10);
}
}
- } while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 100);
+ } while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 1000);
if (wsh->x >= 1000 || (block && wsh->x >= 100)) {
r = -1;
wsh->close_sock = 1;
}
- wsh->buflen = sizeof(wsh->buffer);
+ wsh->buflen = 1024 * 64;
+ wsh->bbuflen = wsh->buflen;
+
+ wsh->buffer = malloc(wsh->buflen);
+ wsh->bbuffer = malloc(wsh->bbuflen);
+ //printf("init %p %ld\n", (void *) wsh->bbuffer, wsh->bbuflen);
+ //memset(wsh->buffer, 0, wsh->buflen);
+ //memset(wsh->bbuffer, 0, wsh->bbuflen);
+
wsh->secure = ssl_ctx ? 1 : 0;
setup_socket(sock);
SSL_free(wsh->ssl);
wsh->ssl = NULL;
}
+
+ if (wsh->buffer) free(wsh->buffer);
+ if (wsh->bbuffer) free(wsh->bbuffer);
+
+ wsh->buffer = wsh->bbuffer = NULL;
+
}
ssize_t ws_close(wsh_t *wsh, int16_t reason)
}
+
+uint64_t hton64(uint64_t val)
+{
+ if (__BYTE_ORDER == __BIG_ENDIAN) return (val);
+ else return __bswap_64(val);
+}
+
+uint64_t ntoh64(uint64_t val)
+{
+ if (__BYTE_ORDER == __BIG_ENDIAN) return (val);
+ else return __bswap_64(val);
+}
+
+
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
{
char *maskp;
int ll = 0;
int frag = 0;
+ int blen;
+
+ wsh->body = wsh->bbuffer;
+ wsh->packetlen = 0;
again:
need = 2;
int fin = (wsh->buffer[0] >> 7) & 1;
int mask = (wsh->buffer[1] >> 7) & 1;
- if (fin) {
- if (*oc == WSOC_CONTINUATION) {
- frag = 1;
- } else {
- frag = 0;
- }
+
+ if (!fin && *oc != WSOC_CONTINUATION) {
+ frag = 1;
+ } else if (fin && *oc == WSOC_CONTINUATION) {
+ frag = 0;
}
if (mask) {
wsh->plen = wsh->buffer[1] & 0x7f;
wsh->payload = &wsh->buffer[2];
-
+
if (wsh->plen == 127) {
uint64_t *u64;
+ int more = 0;
need += 8;
if (need > wsh->datalen) {
/* too small - protocol err */
- *oc = WSOC_CLOSE;
- return ws_close(wsh, WS_PROTO_ERR);
- }
+ //*oc = WSOC_CLOSE;
+ //return ws_close(wsh, WS_PROTO_ERR);
- u64 = (uint64_t *) wsh->payload;
- wsh->payload += 8;
+ more = ws_raw_read(wsh, wsh->buffer + wsh->datalen, need - wsh->datalen, WS_BLOCK);
+
+ if (more < need - wsh->datalen) {
+ *oc = WSOC_CLOSE;
+ return ws_close(wsh, WS_PROTO_ERR);
+ } else {
+ wsh->datalen += more;
+ }
- wsh->plen = ntohl((u_long)*u64);
+ }
+
+ u64 = (uint64_t *) wsh->payload;
+ wsh->payload += 8;
+ wsh->plen = ntoh64(*u64);
} else if (wsh->plen == 126) {
uint16_t *u16;
return ws_close(wsh, WS_PROTO_ERR);
}
- if ((need + wsh->datalen) > (ssize_t)wsh->buflen) {
- /* too big - Ain't nobody got time fo' dat */
- *oc = WSOC_CLOSE;
- return ws_close(wsh, WS_DATA_TOO_BIG);
+ blen = wsh->body - wsh->bbuffer;
+
+ if (need + blen > (ssize_t)wsh->bbuflen) {
+ void *tmp;
+
+ wsh->bbuflen = need + blen + wsh->rplen;
+
+ if ((tmp = realloc(wsh->bbuffer, wsh->bbuflen))) {
+ wsh->bbuffer = tmp;
+ } else {
+ abort();
+ }
+
+ wsh->body = wsh->bbuffer + blen;
}
wsh->rplen = wsh->plen - need;
-
+
+ if (wsh->rplen) {
+ memcpy(wsh->body, wsh->payload, wsh->rplen);
+ }
+
while(need) {
- ssize_t r = ws_raw_read(wsh, wsh->payload + wsh->rplen, need, WS_BLOCK);
+ ssize_t r = ws_raw_read(wsh, wsh->body + wsh->rplen, need, WS_BLOCK);
if (r < 1) {
/* invalid read - protocol err .. */
ssize_t i;
for (i = 0; i < wsh->datalen; i++) {
- wsh->payload[i] ^= maskp[i % 4];
+ wsh->body[i] ^= maskp[i % 4];
}
}
if (*oc == WSOC_PING) {
- ws_write_frame(wsh, WSOC_PONG, wsh->payload, wsh->rplen);
+ ws_write_frame(wsh, WSOC_PONG, wsh->body, wsh->rplen);
goto again;
}
+ *(wsh->body+wsh->rplen) = '\0';
+ wsh->packetlen += wsh->rplen;
+ wsh->body += wsh->rplen;
+
if (frag) {
goto again;
}
-
-
- *(wsh->payload+wsh->rplen) = '\0';
- *data = (uint8_t *)wsh->payload;
- //printf("READ[%ld][%d]-----------------------------:\n[%s]\n-------------------------------\n", wsh->rplen, *oc, (char *)*data);
+ *data = (uint8_t *)wsh->bbuffer;
+
+ //printf("READ[%ld][%d]-----------------------------:\n[%s]\n-------------------------------\n", wsh->packetlen, *oc, (char *)*data);
- return wsh->rplen;
+ return wsh->packetlen;
}
break;
default:
}
}
+#if 0
ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes)
{
return bytes;
}
+
ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc)
{
ssize_t r = 0;
return r;
}
-
+#endif
ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes)
{
hlen += 8;
u64 = (uint64_t *) &hdr[2];
- *u64 = htonl(bytes);
+ *u64 = hton64(bytes);
}
if (wsh->write_buffer_len < (hlen + bytes + 1)) {
typedef struct wsh_s {
ws_socket_t sock;
- char buffer[65536];
- char wbuffer[65536];
+ char *buffer;
+ char *bbuffer;
+ char *body;
char *uri;
size_t buflen;
+ size_t bbuflen;
ssize_t datalen;
ssize_t wdatalen;
char *payload;
ssize_t plen;
ssize_t rplen;
+ ssize_t packetlen;
SSL *ssl;
int handshake;
uint8_t down;