json_object_object_foreach(rootobject, key, val)
{
T one(key);
- N two(json_object_get_string(val));
+ N two(std::string(json_object_get_string(val)));
append(one,two);
}
function VehicleEventType()
{
this.event = [
- "vehicle_info",
- "vehicle_info_wmi",
- "vehicle_info_vin",
- "vehicle_info_vehicle_type",
- "vehicle_info_door_type",
- "vehicle_info_door_type_1st_row",
- "vehicle_info_door_type_2nd_row",
- "vehicle_info_door_type_3rd_row",
- "vehicle_info_fuel_type",
- "vehicle_info_transmission_gear_type",
- "vehicle_info_wheel_info",
- "vehicle_info_wheel_info_radius",
- "vehicle_info_wheel_info_track",
- "running_status",
- "running_status_vehicle_power_mode",
- "running_status_speedometer",
- "running_status_engine_speed",
- "running_status_trip_meter",
- "running_status_trip_meter_1",
- "running_status_trip_meter_2",
- "running_status_trip_meter_1_mileage",
- "running_status_trip_meter_2_mileage",
- "running_status_trip_meter_1_average_speed",
- "running_status_trip_meter_2_average_speed",
- "running_status_trip_meter_1_fuel_consumption",
- "running_status_trip_meter_2_fuel_consumption",
- "running_status_transmission_gear_status",
- "running_status_cruise_control",
- "running_status_cruise_control_status",
- "running_status_cruise_control_speed",
- "running_status_wheel_brake",
- "running_status_lights_status",
- "running_status_lights_status_head",
- "running_status_lights_status_high_beam",
- "running_status_lights_status_turn_left",
- "running_status_lights_status_turn_right",
- "running_status_lights_status_brake",
- "running_status_lights_status_fog_front",
- "running_status_lights_status_fog_rear",
- "running_status_lights_status_hazard",
- "running_status_lights_status_parking",
- "running_status_interior_lights_status",
- "running_status_interior_lights_status_driver",
- "running_status_interior_lights_status_passenger",
- "running_status_interior_lights_status_center",
- "running_status_automatic_headlights",
- "running_status_dynamic_high_beam",
- "running_status_horn",
- "running_status_chime",
- "running_status_fuel",
- "running_status_estimated_range",
- "running_status_engine_oil",
- "running_status_engine_oil_remaining",
- "running_status_engine_oil_change",
- "running_status_engine_oil_temp",
- "running_status_engine_coolant",
- "running_status_engine_coolant_level",
- "running_status_engine_coolant_temp",
- "running_status_steering_wheel_angle",
- "maintenance",
- "maintenance_odometer",
- "maintenance_transmission_oil",
- "maintenance_transmission_oil_life_level",
- "maintenance_transmission_oil_temp",
- "maintenance_brake_fluid_level",
- "maintenance_washer_fluid_level",
- "maintenance_malfunction_indicator_lamp",
- "maintenance_battery",
- "maintenance_battery_voltage",
- "maintenance_battery_current",
- "maintenance_tire_pressure",
- "maintenance_tire_pressure_front_left",
- "maintenance_tire_pressure_front_right",
- "maintenance_tire_pressure_rear_left",
- "maintenance_tire_pressure_rear_right",
- "maintenance_tire_pressure_status",
- "maintenance_tire_pressure_status_front_left",
- "maintenance_tire_pressure_status_front_right",
- "maintenance_tire_pressure_status_rear_left",
- "maintenance_tire_pressure_status_rear_right",
- "personalization",
- "personalization_key_id",
- "personalization_language",
- "personalization_measurement_system",
- "personalization_measurement_system_string",
- "personalization_measurement_system_string_fuel",
- "personalization_measurement_system_string_distance",
- "personalization_measurement_system_string_speed",
- "personalization_measurement_system_string_consumption",
- "personalization_mirror",
- "personalization_mirror_driver",
- "personalization_mirror_passenger",
- "personalization_mirror_inside",
- "personalization_steering_wheel_position",
- "personalization_steering_wheel_position_slide",
- "personalization_steering_wheel_position_tilt",
- "personalization_driving_mode",
- "personalization_driver_seat_position",
- "personalization_driver_seat_position_recline_seatback",
- "personalization_driver_seat_position_slide",
- "personalization_driver_seat_position_cushion_height",
- "personalization_driver_seat_position_headrest",
- "personalization_driver_seat_position_back_cushion",
- "personalization_driver_seat_position_side_cushion",
- "personalization_passenger_seat_position",
- "personalization_passenger_seat_position_recline_seatback",
- "personalization_passenger_seat_position_slide",
- "personalization_passenger_seat_position_cushion_height",
- "personalization_passenger_seat_position_headrest",
- "personalization_passenger_seat_position_back_cushion",
- "personalization_passenger_seat_position_side_cushion",
- "personalization_dashboard_illumination",
- "personalization_generated_vehicle_sound_mode",
- "driving_safety",
- "driving_safety_antilock_braking_system",
- "driving_safety_traction_control_system",
- "driving_safety_electronic_stability_control",
- "driving_safety_vehicle_top_speed_limit",
- "driving_safety_airbag_status",
- "driving_safety_airbag_status_driver",
- "driving_safety_airbag_status_passenger",
- "driving_safety_airbag_status_side",
- "driving_safety_door_open_status",
- "driving_safety_door_open_status_driver",
- "driving_safety_door_open_status_passenger",
- "driving_safety_door_open_status_rear_left",
- "driving_safety_door_open_status_rear_right",
- "driving_safety_door_open_status_trunk",
- "driving_safety_door_open_status_fuel_filter_cap",
- "driving_safety_door_open_status_hood",
- "driving_safety_door_lock_status",
- "driving_safety_door_lock_status_driver",
- "driving_safety_door_lock_status_passenger",
- "driving_safety_door_lock_status_rear_left",
- "driving_safety_door_lock_status_rear_right",
- "driving_safety_child_safety_lock",
- "driving_safety_occupants_status",
- "driving_safety_occupants_status_driver",
- "driving_safety_occupants_status_passenger",
- "driving_safety_occupants_status_rear_left",
- "driving_safety_occupants_status_rear_right",
- "driving_safety_seat_belt",
- "driving_safety_seat_belt_driver",
- "driving_safety_seat_belt_passenger",
- "driving_safety_seat_belt_rear_left",
- "driving_safety_seat_belt_rear_right",
- "driving_safety_window_lock",
- "driving_safety_window_lock_driver",
- "driving_safety_window_lock_passenger",
- "driving_safety_window_lock_rear_left",
- "driving_safety_window_lock_rear_right",
- "driving_safety_obstacle_distance",
- "driving_safety_obstacle_distance_sensor_status",
- "driving_safety_obstacle_distance_front_center",
- "driving_safety_obstacle_distance_rear_center",
- "driving_safety_obstacle_distance_front_left",
- "driving_safety_obstacle_distance_front_right",
- "driving_safety_obstacle_distance_middle_left",
- "driving_safety_obstacle_distance_middle_right",
- "driving_safety_obstacle_distance_rear_left",
- "driving_safety_obstacle_distance_rear_right",
- "driving_safety_front_collision_detection",
- "driving_safety_front_collision_detection_status",
- "driving_safety_front_collision_detection_distance",
- "driving_safety_front_collision_detection_time",
- "vision_system",
- "vision_system_lane_departure_detection_status",
- "vision_system_lane_departed",
- "parking",
- "parking_security_alert",
- "parking_parking_brake",
- "parking_parking_lights",
- "climate_environment_interior_temp",
- "climate_environment_exterior_temp",
- "climate_environment_exterior_brightness",
- "climate_environment_rain_sensor",
- "climate_environment_windshield_wiper",
- "climate_environment_rear_wiper",
- "climate_environment_hvac_fan",
- "climate_environment_hvac_fan_direction",
- "climate_environment_hvac_fan_speed",
- "climate_environment_hvac_fan_target_temp",
- "climate_environment_air_conditioning",
- "climate_environment_air_recirculation",
- "climate_environment_heater",
- "climate_environment_defrost",
- "climate_environment_defrost_windshield",
- "climate_environment_defrost_rear_window",
- "climate_environment_defrost_side_mirrors",
- "climate_environment_steering_wheel_heater",
- "climate_environment_seat_heater",
- "climate_environment_seat_cooler",
- "climate_environment_window",
- "climate_environment_window_driver",
- "climate_environment_window_passenger",
- "climate_environment_window_rear_left",
- "climate_environment_window_rear_right",
- "climate_environment_sunroof",
- "climate_environment_sunroof_openness",
- "climate_environment_sunroof_tilt",
- "climate_environment_convertible_roof"
+"Randomize",
+"AirConditioning",
+"AirRecirculation",
+"AirflowDirection",
+"AvgKW",
+"BatteryStatus",
+"ChildLock",
+"Defrost",
+"ExteriorBrightness",
+"ExteriorTemperature",
+"FanSpeed",
+"FrontWheelRadius",
+"FullBatteryRange",
+"InteriorTemperature",
+"LightHazard",
+"LightHead",
+"LightParking",
+"NightMode",
+"Odometer",
+"SeatHeater",
+"TargetTemperature",
+"TransmissionShiftPosition",
+"VehicleSpeed",
+"Weather"
];
this.value = [];
<title>IVI API Tester</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css"/>
- <script src="api.js"></script>
+ <script src="vehicle.js"></script>
</head>
<body onload="init()">
<div id="result">
top: 0px;
left: 0%;
height: 100%;
- width: 520px;
+ width: 620px;
overflow-y: auto;
}
#result {
position: absolute;
top: 0px;
- left: 520px;
+ left: 620px;
height: 98%;
width: 1380px;
padding-top: 1%;
position: relative;
left: 0px;
height: 67px;
- width: 500px;
+ width: 700px;
overflow: hidden;
}
top: 32px;
left: 0px;
height: 35px;
- width: 430px;
+ width: 630px;
}
+.smallText {
+ text-align: left;
+ color: #FFFFFF;
+ font: 18px Arial;
+ display: inline;
+}
.propinfo {
position: absolute;
top: 0px;
left: 0px;
height: 67px;
- width: 500px;
+ width: 600px;
text-align: left;
color: #FFFFFF;
font: 18px Arial;
/* --------------------------- utility code ------------------------------- */
var PRINT = {
- logElement : null,
- init : function(log_id) {
+ logElement: null,
+ init: function(log_id) {
this.logElement = document.getElementById(log_id);
},
- scrollToBottom : function() {
+ scrollToBottom: function() {
this.logElement.scrollTop = this.logElement.scrollHeight;
},
- clear : function() {
+ clear: function() {
this.logElement.innerHTML = "";
},
- pass : function(msg) {
+ pass: function(msg) {
this.logElement.innerHTML += "<div class='PassClass'>PASS: " + msg + "</div>";
this.scrollToBottom();
},
- fail : function(msg) {
+ fail: function(msg) {
this.logElement.innerHTML += "<div class='FailClass'>FAIL: " + msg + "</div>";
this.scrollToBottom();
},
- log : function(msg) {
+ log: function(msg) {
this.logElement.innerHTML += "<div class='LogClass'> " + msg + "</div>";
this.scrollToBottom();
},
var vehicleEventType = new VehicleEventType();
var selected = [];
-function getTypes(event)
-{
+function getTypes(event) {
var types = window.vehicle.getSupportedEventTypes(event, false,
function(data) {
- if(data && data.length > 1)
- {
- PRINT.pass(event+" is a set of "+data.length+" events:");
- for(i in data)
- {
+ if (data && data.length > 1) {
+ PRINT.pass(event + " is a set of " + data.length + " events:");
+ for (i in data) {
PRINT.log(data[i]);
}
- }
- else if(data && data.length > 0)
- {
- PRINT.pass(event+" is a single event:");
- for(i in data)
- {
+ } else if (data && data.length > 0) {
+ PRINT.pass(event + " is a single event:");
+ for (i in data) {
PRINT.log(data[i]);
}
- }
- else
- {
- PRINT.fail(event+" unexcepted empty data field");
+ } else {
+ PRINT.fail(event + " unexcepted empty data field");
}
},
function(msg) {
- PRINT.fail(((event === "")?"all events":event)+":<br>"+msg);
+ PRINT.fail(((event === "") ? "all events" : event) + ":<br>" + msg);
}
);
}
-function updateInput(input, value)
-{
+function updateInput(input, value) {
input.value = value;
input.className = "change";
input.addEventListener('webkitTransitionEnd', function callback(e) {
}, false);
}
-function getValue(eventlist)
-{
- var types = window.vehicle.get(eventlist,
+function getValue(eventlist) {
+ var zoneList = getZone(eventlist);
+ var types = window.vehicle.get(eventlist, zoneList,
function(data) {
- if(data && data.length > 0)
- {
+ if (data) {
PRINT.pass("values received:");
- var list = [];
- for(var i = 0; i < data.length; i++)
- {
- list[i] = data[i].name;
- PRINT.log(data[i].name+": "+data[i].value);
- }
+ if (eventlist.length > 1 && !! data.length && data.length > 0) {
+ var list = [];
+ for (var i = 0; i < data.length; i++) {
+ list[i] = data[i].property;
+ //list[i] = data[i].name; ???
+ PRINT.log(data[i].property + ": " + data[i].value + ", zone: " + data[i].zone);
+ //PRINT.log(data[i].name+": "+data[i].value); ???
+ }
- var elements = document.getElementsByClassName('proptest');
- for (var i = 0; i < elements.length; i++) {
- var propinfo = elements[i].getElementsByClassName('propinfo')[0];
- var name = propinfo.innerHTML;
- var idx = list.indexOf(name);
- if(idx >= 0)
- {
- var input = elements[i].getElementsByTagName('input')[0];
- updateInput(input, data[idx].value);
+ var elements = document.getElementsByClassName('proptest');
+ for (var i = 0; i < elements.length; i++) {
+ var propinfo = elements[i].getElementsByClassName('propinfo')[0];
+ var name = propinfo.innerHTML;
+ var idx = list.indexOf(name);
+ if (idx >= 0) {
+ var zone = elements[i].getElementsByTagName('input')[1];
+ updateInput(zone, zone.value);
+ var input = elements[i].getElementsByTagName('input')[0];
+ updateInput(input, data[idx].value);
+ }
+ }
+ } else {
+ PRINT.log(JSON.stringify(data));
+ var elements = document.getElementsByClassName('proptest');
+ for (var i = 0; i < elements.length; i++) {
+ var propinfo = elements[i].getElementsByClassName('propinfo')[0];
+ if (data.property == propinfo.innerHTML) {
+ var zone = elements[i].getElementsByTagName('input')[1];
+ updateInput(zone, zone.value);
+ var input = elements[i].getElementsByTagName('input')[0];
+ updateInput(input, data.value);
+ }
}
}
- }
- else
- {
- PRINT.fail("no values retrieved for "+eventlist);
+ } else {
+ PRINT.fail("no values retrieved for " + eventlist);
}
},
function(msg) {
);
}
-function setValue(eventlist)
-{
+function setValue(eventlist) {
+ var zoneList = getZone(eventlist);
var elements = document.getElementsByClassName('proptest');
- var i, valuelist = [];
+ var i, valuelist = [] ;
/* initialize the value list */
for (i = 0; i < eventlist.length; i++) {
var propinfo = elements[i].getElementsByClassName('propinfo')[0];
var name = propinfo.innerHTML;
var idx = eventlist.indexOf(name);
- if(idx >= 0)
- {
- var input = elements[i].getElementsByTagName('input')[0];
- valuelist[idx] = input.value;
+ if (idx >= 0) {
+
+ var input = elements[i].getElementsByTagName('input')[0];
+ valuelist[idx] = input.value;
}
}
- var types = window.vehicle.set(eventlist, valuelist,
+ var types = window.vehicle.set(eventlist, valuelist, zoneList,
function(msg) {
- PRINT.pass(msg);
+ PRINT.pass("Set success for: " + JSON.stringify(msg));
},
function(msg) {
- PRINT.fail(msg);
+ PRINT.fail("Set error: " + JSON.stringify(msg));
}
);
}
-function eventListener(e)
-{
+function eventListener(e) {
+ PRINT.log(e.name + " update: " + JSON.stringify(e.value));
var elements = document.getElementsByClassName('proptest');
for (var i = 0; i < elements.length; i++) {
var propinfo = elements[i].getElementsByClassName('propinfo')[0];
var name = propinfo.innerHTML;
- if(name === e.name)
- {
+ if (name === e.name) {
var input = elements[i].getElementsByTagName('input')[0];
- updateInput(input, e.value);
+ updateInput(input, e.value.value);
+ var zone = elements[i].getElementsByTagName('input')[1];
+ updateInput(zone, e.value.zone);
}
}
}
-function subscribe(eventlist)
-{
- window.vehicle.subscribe(eventlist,
+function subscribe(eventlist) {
+ var zoneList = getZone(eventlist);
+ window.vehicle.subscribe(eventlist, zoneList,
function(data) {
- PRINT.pass("Subscribe success for: "+data);
- for(var i = 0; i < data.length; i++)
- {
- var sub = data[i]+"_subscribe";
- var unsub = data[i]+"_unsubscribe";
-// document.getElementById(sub).className = "testbutton subscribe disable"
-// document.getElementById(unsub).className = "testbutton unsubscribe";
+ PRINT.pass("Subscribe success for: " + data);
+ for (var i = 0; i < data.length; i++) {
+ var sub = data[i] + "_subscribe";
+ var unsub = data[i] + "_unsubscribe";
+ // document.getElementById(sub).className = "testbutton subscribe disable"
+ // document.getElementById(unsub).className = "testbutton unsubscribe";
document.addEventListener(data[i], eventListener, false);
}
},
function(msg) {
- PRINT.fail("Subscribe failed for: "+msg);
+ PRINT.fail("Subscribe failed for: " + msg);
}
);
}
-function unsubscribe(eventlist)
-{
+function unsubscribe(eventlist, zoneList) {
+ zoneList = getZone(eventlist);
/* kill the handers first, so even if the service fails to acknowledge */
/* we've stopped listening */
- for(var i = 0; i < eventlist.length; i++)
- {
+ for (var i = 0; i < eventlist.length; i++) {
document.removeEventListener(eventlist[i], eventListener, false);
}
- window.vehicle.unsubscribe(eventlist,
+ window.vehicle.unsubscribe(eventlist, zoneList,
function(data) {
- PRINT.pass("Unsubscribe success for: "+data);
- for(var i = 0; i < data.length; i++)
- {
- var sub = data[i]+"_subscribe";
- var unsub = data[i]+"_unsubscribe";
-// document.getElementById(unsub).className = "testbutton unsubscribe disable";
-// document.getElementById(sub).className = "testbutton subscribe";
+ PRINT.pass("Unsubscribe success for: " + data);
+ for (var i = 0; i < data.length; i++) {
+ var sub = data[i] + "_subscribe";
+ var unsub = data[i] + "_unsubscribe";
+ // document.getElementById(unsub).className = "testbutton unsubscribe disable";
+ // document.getElementById(sub).className = "testbutton subscribe";
}
},
function(msg) {
- PRINT.fail("Unsubscribe failed for: "+msg);
+ PRINT.fail("Unsubscribe failed for: " + msg);
}
);
}
-function select(elem)
-{
+function getZone(eventlist) {
+ var list = [];
+ if (eventlist.length > 1) {
+
+ // for (var i = 0; i < data.length; i++) {
+ // list[i] = data[i].property;
+ // //list[i] = data[i].name; ???
+ // PRINT.log(data[i].property + ": " + data[i].value);
+ // //PRINT.log(data[i].name+": "+data[i].value); ???
+ // }
+
+ var elements = document.getElementsByClassName('proptest');
+ for (var i = 0; i < elements.length; i++) {
+ var propinfo = elements[i].getElementsByClassName('propinfo')[0];
+ var name = propinfo.innerHTML;
+ var idx = eventlist.indexOf(name);
+ if (idx >= 0) {
+ var zone = elements[i].getElementsByTagName('input')[1];
+ list.push(zone.value);
+ }
+ }
+ } else {
+ var elements = document.getElementsByClassName('proptest');
+ for (var i = 0; i < elements.length; i++) {
+ var propinfo = elements[i].getElementsByClassName('propinfo')[0];
+ if (eventlist[0] == propinfo.innerHTML) {
+ var zone = elements[i].getElementsByTagName('input')[1];
+ list.push(zone.value);
+ }
+ }
+ }
+ return list.join();
+}
+
+function select(elem) {
var name = elem.innerHTML;
- if(!vehicleEventType.isValid(name))
+ if (!vehicleEventType.isValid(name))
return;
var idx = selected.indexOf(name);
- if(elem.className == "propinfo")
- {
- if(idx < 0)
- {
+ if (elem.className == "propinfo") {
+ if (idx < 0) {
selected[selected.length] = name;
}
elem.className = "propinfo select";
- }
- else if(elem.className == "propinfo select")
- {
- if(idx >= 0)
- {
+ } else if (elem.className == "propinfo select") {
+ if (idx >= 0) {
selected.splice(idx, 1);
}
elem.className = "propinfo";
}
}
-function start(msg)
-{
- if(window.vehicle && window.vehicle.getSupportedEventTypes)
- {
- PRINT.pass("vehicle interface online "+msg);
- }
- else
- {
+function start(msg) {
+ if (window.vehicle && window.vehicle.getSupportedEventTypes) {
+ PRINT.pass("vehicle interface online " + msg);
+ } else {
PRINT.fail("vehicle interface not found");
return;
}
var tester = document.getElementById("tester");
var part = ['<div class="proptest"><div class="propinfo" onclick=select(this)>',
- '</div><div class="buttons"><div class="testbutton types" onclick=getTypes("',
- '")></div><div id="',
- '_subscribe" class="testbutton subscribe" onclick=subscribe(["',
- '"])></div><div id="',
- '_unsubscribe" class="testbutton unsubscribe" onclick=unsubscribe(["',
- '"])></div><div class="testbutton get" onclick=getValue(["',
- '"])></div><div class="testbutton set" onclick=setValue(["',
- '"])></div><input type="text" value="0"/></div></div>'
+ '</div><div class="buttons"><div class="testbutton types" onclick=getTypes("',
+ '")></div><div id="',
+ '_subscribe" class="testbutton subscribe" onclick=subscribe(["',
+ '"])></div><div id="',
+ '_unsubscribe" class="testbutton unsubscribe" onclick=unsubscribe(["',
+ '"])></div><div class="testbutton get" onclick=getValue(["',
+ '"])></div><div class="testbutton set" onclick=setValue(["',
+ '"])></div><input class = "Textvalue" type="text" value="0" placeholder="Value" /><div class = "smallText"> Zone: </div><input class = "zone" type="text" value="0" placeholder="Zone"/></div></div>'
];
var events = vehicleEventType.event;
/* apply on all selected events */
- var html = '<div class="proptest"><div class="propinfo unselectable">apply on all selected events'+
- '</div><div class="buttons">'+
- '<div class="testbutton subscribe" onclick=subscribe(selected)></div>'+
- '<div class="testbutton unsubscribe" onclick=unsubscribe(selected)></div>'+
- '<div class="testbutton get" onclick=getValue(selected)></div>'+
- '<div class="testbutton set" onclick=setValue(selected)></div></div></div>'
+ var html = '<div class="proptest"><div class="propinfo unselectable">apply on all selected events' +
+ '</div><div class="buttons">' +
+ '<div class="testbutton subscribe" onclick=subscribe(selected)></div>' +
+ '<div class="testbutton unsubscribe" onclick=unsubscribe(selected)></div>' +
+ '<div class="testbutton get" onclick=getValue(selected)></div>' +
+ '<div class="testbutton set" onclick=setValue(selected)></div></div></div>';
/* all events */
- html += '<div class="proptest"><div class="propinfo unselectable">all events'+
- '</div><div class="buttons"><div class="testbutton types" onclick=getTypes("'+
- '")></div><div class="testbutton subscribe" onclick=subscribe(["'+
- '"])></div><div class="testbutton unsubscribe" onclick=unsubscribe(["'+
- '"])></div><div class="testbutton get" onclick=getValue(["'+
- '"])></div></div></div>';
+ html += '<div class="proptest"><div class="propinfo unselectable">all events';
+ html += '</div><div class="buttons"><div class="testbutton types" onclick=getTypes("' ;
+ html += '")></div><div class="testbutton subscribe" onclick=\"subscribe([\'' ;
+ html += events.join("','") ;
+ html += '\'])\"></div><div class="testbutton unsubscribe" onclick= \"unsubscribe([\'' ;
+ html += events.join("','");
+ html += '\'])\"></div><div class="testbutton get" onclick=\"getValue([\'' ;
+ html += events.join("','");
+ html += '\'])\"></div></div></div>';
/* events */
- for(var i = 0; i < events.length; i++)
- {
+ for (var i = 0; i < events.length; i++) {
var piece = "";
- for(var j = 0; j < part.length - 1; j++)
- {
+ for (var j = 0; j < part.length - 1; j++) {
piece += part[j] + events[i];
}
html += piece + part[j];
tester.innerHTML = html;
}
-function error(msg)
-{
+function error(msg) {
PRINT.fail(msg);
}
* errorCB: error callback, called with the eventlist that failed to unsubscribe
*
******************************************************************************/
-
+/*
+(function () {
+*/
function Vehicle(sCB, eCB, url, protocol)
{
/* store a copy of Vehicle this for reference in callbacks */
this.socketProtocol = "http-only";
/* override the websocket address if parameters are given */
- if(url != undefined) this.socketUrl = url;
- if(protocol != undefined) this.socketProtocol = protocol;
+ if(url !== undefined) this.socketUrl = url;
+ if(protocol !== undefined) this.socketProtocol = protocol;
this.VehicleMethodCall = function(id, name, successCB, errorCB)
{
this.start = function()
{
me.timeout = setTimeout(function(){
- if(me.errorCB != undefined)
+ if(me.errorCB !== undefined)
{
me.errorCB("\""+me.name+"\" method timed out after "+self.timeouttime+"ms");
}
}
this.finish = function()
{
- if(me.timeout != undefined)
+ if(me.timeout !== undefined)
{
clearTimeout(me.timeout);
}
{
if(!this.connected)
{
- if(errorCB != undefined)
+ if(errorCB !== undefined)
{
errorCB("\""+obj.name+"\" method failed because socket is closed");
}
this.send(obj, successCB, errorCB);
}
-Vehicle.prototype.get = function(namelist, successCB, errorCB)
+Vehicle.prototype.get = function(namelist, zone, successCB, errorCB)
{
if(namelist.length <= 0)
{
return;
}
+ var properties = [];
+
+ for(var i = 0; i < namelist.length; i++)
+ {
+ properties[i] = {"property" : namelist[i], "zone" : zone};
+ }
var obj = {
"type" : "method",
"name": "get",
"transactionid" : this.generateTransactionId(),
- "data" : namelist
+ "data" : properties
};
this.send(obj, successCB, errorCB);
}
}
-Vehicle.prototype.set = function(namelist, valuelist, successCB, errorCB)
+Vehicle.prototype.set = function(namelist, valuelist, zoneList, successCB, errorCB)
{
if((namelist.length != valuelist.length)||(namelist.length <= 0))
{
var list = [];
for(var i = 0; i < namelist.length; i++)
{
- var val = {"property" : namelist[i], "value" : valuelist[i]};
+ var val = {"property" : namelist[i], "value" : valuelist[i],"zone" : zoneList[i]};
list[list.length] = val;
}
obj.data = list;
this.send(obj, successCB, errorCB);
}
-Vehicle.prototype.subscribe = function(namelist, successCB, errorCB)
+Vehicle.prototype.subscribe = function(namelist, zoneList, successCB, errorCB)
{
var obj = {
"type" : "method",
"name": "subscribe",
"transactionid" : this.generateTransactionId(),
- "data" : namelist
+ "data" : namelist,
+ "zone" : zoneList
};
this.send(obj, successCB, errorCB);
}
-Vehicle.prototype.unsubscribe = function(namelist, successCB, errorCB)
+Vehicle.prototype.unsubscribe = function(namelist, zoneList, successCB, errorCB)
{
var obj = {
"type" : "method",
"name": "unsubscribe",
"transactionid" : this.generateTransactionId(),
- "data" : namelist
+ "data" : namelist,
+ "zone" : zoneList
};
this.send(obj, successCB, errorCB);
}
if(call&&(!call.done)&&(call.transactionid === event.transactionid))
{
call.finish();
- if(event.error != undefined)
+ if(event.error !== undefined)
{
call.errorCB(event.error);
}
- if(event.data != undefined)
+ else if(event.data !== undefined && call.successCB !== undefined)
{
call.successCB(event.data);
}
}
}
}
+
+/*
+ // AMD / RequireJS
+ if (typeof define !== 'undefined' && define.amd) {
+ define([], function () {
+ return {
+ Vehicle: Vehicle
+ };
+ });
+ }
+ // Node.js
+ else if (typeof module !== 'undefined' && module.exports) {
+ module.exports = {
+ Vehicle: Vehicle
+ };
+ }
+ // included directly via <script> tag
+ else {
+ root.vehicle = {
+ Vehicle: Vehicle
+ };
+ }
+})();
+*/
s.precision(15);
s << "{\"type\":\"valuechanged\",\"name\":\"" << tmpstr << "\",\"data\":";
- s << "{ \"value\":\"" << value->toString() << "\",\"timestamp\":\""<<value->timestamp<<"\",\"sequence\":\""<<value->sequence<<"\"},";
+ s << "{ \"value\":\"" << value->toString() << "\",\"zone\":\""<<value->zone;
+ s << "\",\"timestamp\":\""<<value->timestamp<<"\",\"sequence\":\""<<value->sequence<<"\"},";
s << "\"transactionid\":\"" << m_uuid << "\"}";
string replystr = s.str();
new_response+=LWS_SEND_BUFFER_PRE_PADDING;
strcpy(new_response,replystr.c_str());
libwebsocket_write(m_wsi, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
- delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
+ delete [] (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
}
WebSocketSink::~WebSocketSink()
{
#include <json/json_object.h>
#include <json/json_tokener.h>
#include <listplusplus.h>
+#include <memory>
+
#define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
//Global variables, these will be moved into the class
static int websocket_callback(struct libwebsocket_context *context,struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason, void *user,void *in, size_t len);
bool gioPollingFunc(GIOChannel *source,GIOCondition condition,gpointer data);
+// libwebsocket_write helper function
+static int lwsWrite(struct libwebsocket *lws, const std::string& strToWrite)
+{
+ std::unique_ptr<char[]> buffer(new char[LWS_SEND_BUFFER_PRE_PADDING + strToWrite.length() + LWS_SEND_BUFFER_POST_PADDING]);
+
+ char *buf = buffer.get() + LWS_SEND_BUFFER_PRE_PADDING;
+ strcpy(buf, strToWrite.c_str());
+ //NOTE: delete[] on buffer is not needed since std::unique_ptr<char[]> is used
+ return libwebsocket_write(lws, (unsigned char*)buf, strToWrite.length(), LWS_WRITE_TEXT);
+}
WebSocketSinkManager::WebSocketSinkManager(AbstractRoutingEngine* engine, map<string, string> config):AbstractSinkManager(engine, config)
{
}
void WebSocketSinkManager::init()
{
- //Protocol list for libwebsockets.
+ //Protocol list for libwebsockets.
protocollist[0] = { "http-only", websocket_callback, 0 };
protocollist[1] = { NULL, NULL, 0 };
}
-void WebSocketSinkManager::addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property,string id)
+void WebSocketSinkManager::addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property, Zone::Type zone, string id)
{
- AsyncPropertyRequest velocityRequest;
- if (property == "running_status_speedometer")
- {
- velocityRequest.property = VehicleProperty::VehicleSpeed;
- }
- else if (property == "running_status_engine_speed")
- {
- velocityRequest.property = VehicleProperty::EngineSpeed;
- }
- else if (property == "running_status_steering_wheel_angle")
+ AsyncPropertyRequest request;
+ PropertyList foo = VehicleProperty::capabilities();
+ if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(property))
{
- velocityRequest.property = VehicleProperty::SteeringWheelAngle;
+ request.property = property;
}
- else if (property == "running_status_transmission_gear_status")
+ else
{
- velocityRequest.property = VehicleProperty::TransmissionShiftPosition;
+ DebugOut(0)<<"websocketsink: Invalid property requested: "<<property;
+ return;
}
- else
+
+ request.zoneFilter = zone;
+ request.completed = [socket,id,property](AsyncPropertyReply* reply)
{
- PropertyList foo = VehicleProperty::capabilities();
- if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(property))
- {
- velocityRequest.property = property;
- }
- else
- {
- DebugOut(0)<<"websocketsink: Invalid property requested: "<<property;
+ DebugOut()<<"Got property: "<<reply->property.c_str()<<endl;
+ if(!reply->value){
+ DebugOut()<<"Property value is null"<<endl;
+ delete reply;
return;
}
- }
- velocityRequest.completed = [socket,id,property](AsyncPropertyReply* reply)
- {
- DebugOut()<<"Got property: "<<reply->value->toString().c_str()<<endl;
- //uint16_t velocity = boost::any_cast<uint16_t>(reply->value);
stringstream s;
s.precision(15);
- //TODO: Dirty hack hardcoded stuff, jsut to make it work.
- string tmpstr = "";
- tmpstr = property;
-
- /// TODO: timestamp and sequence need to be inside the "data" object:
s << "{\"type\":\"methodReply\",\"name\":\"get\",\"data\":{";
- s << "\"property\":\"" << tmpstr << "\",\"value\":\"" << reply->value->toString() << "\",\"timestamp\":\""<<reply->value->timestamp<<"\",";
+ s << "\"property\":\"" << property << "\",\"zone\":\"" << reply->value->zone << "\",\"value\":\"" << reply->value->toString() << "\",\"timestamp\":\""<<reply->value->timestamp<<"\",";
s <<"\"sequence\": \""<<reply->value->sequence<<"\"}";
s << ",\"transactionid\":\"" << id << "\"}";
-
string replystr = s.str();
//printf("Reply: %s\n",replystr.c_str());
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Reply:" << replystr << endl;
- char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
- new_response+=LWS_SEND_BUFFER_PRE_PADDING;
- strcpy(new_response,replystr.c_str());
- libwebsocket_write(socket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
+ lwsWrite(socket, replystr);
- //TODO: run valgrind on this. libwebsocket's documentation says NOTHING about this, yet malloc insists it's true.
- //delete new_response; <- Unneeded. Apparently libwebsocket free's it.
- delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING); //Needs to subtract pre-padding, to get back to the start of the pointer.
delete reply;
};
- AsyncPropertyReply* reply = routingEngine->getPropertyAsync(velocityRequest);
+ AsyncPropertyReply* reply = routingEngine->getPropertyAsync(request);
}
void WebSocketSinkManager::addSingleShotRangedSink(libwebsocket* socket, PropertyList properties, double start, double end, double seqstart,double seqend, string id)
{
stringstream s;
- //TODO: Dirty hack hardcoded stuff, jsut to make it work.
stringstream data;
data.precision(15);
data<< "[";
//printf("Reply: %s\n",replystr.c_str());
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Reply:" << replystr << "\n";
- char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
- new_response+=LWS_SEND_BUFFER_PRE_PADDING;
- strcpy(new_response,replystr.c_str());
- libwebsocket_write(socket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
+ lwsWrite(socket, replystr);
- //TODO: run valgrind on this. libwebsocket's documentation says NOTHING about this, yet malloc insists it's true.
- //delete new_response; <- Unneeded. Apparently libwebsocket free's it.
- delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING); //Needs to subtract pre-padding, to get back to the start of the pointer.
delete reply;
};
//printf("Reply: %s\n",replystr.c_str());
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Reply:" << replystr << "\n";
- char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
- new_response+=LWS_SEND_BUFFER_PRE_PADDING;
- strcpy(new_response,replystr.c_str());
- libwebsocket_write(socket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
- delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
+ lwsWrite(socket, replystr);
}
}
-void WebSocketSinkManager::setValue(string property,string value)
+void WebSocketSinkManager::setValue(libwebsocket* socket,VehicleProperty::Property property,string value,Zone::Type zone,string uuid)
{
AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value);
AsyncSetPropertyRequest request;
request.property = property;
request.value = type;
- request.completed = [](AsyncPropertyReply* reply)
+ request.zoneFilter = zone;
+ request.completed = [&](AsyncPropertyReply* reply)
{
///TODO: do something here on !reply->success
+ stringstream s;
+ s << "{\"type\":\"methodReply\",\"name\":\"set\",\"data\":[{\"property\":\"" << property << "\",\"zone\":" << reply->zoneFilter
+ << "}],\"transactionid\":\"" << uuid << "\"";
+ if(!reply->success)
+ s << ",\"error\":\"method call failed\"";
+ s << "}";
+
+ string replystr = s.str();
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Reply:" << replystr << "\n";
+
+ lwsWrite(socket, replystr);
+
delete reply;
};
{
stringstream s;
- //TODO: Dirty hack hardcoded stuff, jsut to make it work.
string tmpstr = "";
- if (property == "running_status_speedometer")
- {
- tmpstr = VehicleProperty::VehicleSpeed;
- }
- else if (property == "running_status_engine_speed")
- {
- tmpstr = VehicleProperty::EngineSpeed;
- }
- else if (property == "running_status_steering_wheel_angle")
- {
- tmpstr = VehicleProperty::SteeringWheelAngle;
- }
- else if (property == "running_status_transmission_gear_status")
- {
- tmpstr = VehicleProperty::TransmissionShiftPosition;
- }
- else
{
PropertyList foo = VehicleProperty::capabilities();
if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(property))
//printf("Reply: %s\n",replystr.c_str());
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Reply:" << replystr << "\n";
- char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
- new_response+=LWS_SEND_BUFFER_PRE_PADDING;
- strcpy(new_response,replystr.c_str());
- libwebsocket_write(socket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
- delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
+ lwsWrite(socket, replystr);
+
WebSocketSink *sink = new WebSocketSink(m_engine,socket,uuid,property,tmpstr);
m_sinkMap[property].push_back(sink);
}
for (auto i=m_sinkMap.begin(); i != m_sinkMap.end();i++)
{
std::list<WebSocketSink*> *sinks = & (*i).second;
- for (auto sinkItr = sinks->begin(); sinkItr != sinks->end(); sinkItr++)
+ for (auto sinkItr = sinks->begin(); sinkItr != sinks->end(); sinkItr++)
{
if ((*sinkItr)->socket() == socket)
{
vector<string> data;
list<string> key;
list<string> value;
+ list<Zone::Type> zone;
json_object *dataobject = json_object_object_get(rootobject,"data");
if (json_object_get_type(dataobject) == json_type_array)
{
{
json_object *propobject = json_object_object_get(arrayobject,"property");
json_object *valueobject = json_object_object_get(arrayobject,"value");
- string keystr = string(json_object_get_string(propobject));
- string valuestr = string(json_object_get_string(valueobject));
+ json_object *zoneobject = json_object_object_get(arrayobject,"zone");
+ string keystr = string(propobject ? json_object_get_string(propobject) : "");
+ string valuestr = string(valueobject ? json_object_get_string(valueobject): "");
key.push_back(keystr);
value.push_back(valuestr);
+ Zone::Type z(Zone::None);
+ if(zoneobject){
+ try {
+ z = static_cast<Zone::Type>(boost::lexical_cast<int,std::string>(json_object_get_string(zoneobject)));
+ } catch (...) { }
+ }
+ zone.push_back(z);
json_object_put(propobject);
json_object_put(valueobject);
+ json_object_put(zoneobject);
}
else if (json_object_get_type(arrayobject) == json_type_string)
{
if (data.size() > 0)
{
//GetProperty is going to be a singleshot sink.
- //string arg = arguments.front();
- sinkManager->addSingleShotSink(wsi,data.front(),id);
+ sinkManager->addSingleShotSink(wsi,data.front(),Zone::None,id);
+ }
+ else if (key.size() > 0 && key.size() == zone.size())
+ {
+ //GetProperty is going to be a singleshot sink.
+ sinkManager->addSingleShotSink(wsi,key.front(),zone.front(),id);
}
else
{
{
if (data.size() > 0)
{
- //Should not happen
+ //Should not happen
}
else if (value.size() > 0)
{
else
{
list<string>::iterator d = value.begin();
- for (list<string>::iterator i=key.begin();i!=key.end();i++)
+ list<Zone::Type>::iterator z = zone.begin();
+ for (list<string>::iterator i=key.begin();i!=key.end();++i)
{
- DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "websocketsinkmanager setting" << (*i) << "to" << (*d) << "\n";
+ DebugOut() << __SMALLFILE__ << ":" << __LINE__ <<
+ "websocketsinkmanager setting " << (*i) << "to " << (*d) << "in zone " << (*z) << "\n";
//(*i);
- sinkManager->setValue((*i),(*d));
+ sinkManager->setValue(wsi,(*i),(*d),(*z), id);
//(*d);
- d++;
+ ++d;
+ ++z;
}
}
if (data.size() == 0)
{
//Send what properties we support
- typessupported = "\"running_status_speedometer\",\"running_status_engine_speed\",\"running_status_steering_wheel_angle\",\"running_status_transmission_gear_status\"";
-
PropertyList foo = sinkManager->getSupportedProperties();
PropertyList::const_iterator i=foo.cbegin();
while (i != foo.cend())
{
- typessupported.append(",\"").append((*i)).append("\"");
+ if(i==foo.cbegin())
+ typessupported.append("\"").append((*i)).append("\"");
+ else
+ typessupported.append(",\"").append((*i)).append("\"");
i++;
}
}
else
{
//Send what events a particular property supports
- if (data.front()== "running_status_speedometer")
- {
- typessupported = "\"get\",\"subscribe\",\"unsubscribe\",\"getSupportedEventTypes\"";
- }
- else if (data.front()== "running_status_engine_speed")
- {
- typessupported = "\"get\",\"subscribe\",\"unsubscribe\",\"getSupportedEventTypes\"";
- }
- else if (data.front() == "running_status_steering_wheel_angle")
- {
- typessupported = "\"get\",\"subscribe\",\"unsubscribe\",\"getSupportedEventTypes\"";
- }
- else if (data.front() == "running_status_transmission_gear_status")
+ PropertyList foo = sinkManager->getSupportedProperties();
+ if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(data.front()))
{
+ //sinkManager->addSingleShotSink(wsi,data.front(),id);
typessupported = "\"get\",\"subscribe\",\"unsubscribe\",\"getSupportedEventTypes\"";
}
- else
- {
- PropertyList foo = sinkManager->getSupportedProperties();
- if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(data.front()))
- {
- //sinkManager->addSingleShotSink(wsi,data.front(),id);
- typessupported = "\"get\",\"subscribe\",\"unsubscribe\",\"getSupportedEventTypes\"";
- }
- }
}
stringstream s;
string s2;
string replystr = s.str();
DebugOut() << __SMALLFILE__ << ":" << __LINE__ << " JSON Reply: " << replystr << "\n";
//printf("Reply: %s\n",replystr.c_str());
- char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
- new_response+=LWS_SEND_BUFFER_PRE_PADDING;
- strcpy(new_response,replystr.c_str());
- libwebsocket_write(wsi, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
- delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
+ lwsWrite(wsi, replystr);
}
else
{
{
public:
WebSocketSinkManager(AbstractRoutingEngine* engine, map<string, string> config);
- void addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property,string id);
+ void addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property, Zone::Type zone, string id);
void addSingleShotRangedSink(libwebsocket* socket, PropertyList properties,double start, double end, double seqstart,double seqend, string id);
void addSink(libwebsocket* socket, VehicleProperty::Property property,string uuid);
void disconnectAll(libwebsocket* socket);
void init();
map<std::string, list<WebSocketSink*> > m_sinkMap;
void setConfiguration(map<string, string> config);
- void setValue(string property,string value);
+ void setValue(libwebsocket* socket,VehicleProperty::Property property,string value, Zone::Type zone, string uuid);
list<VehicleProperty::Property> getSupportedProperties();
private:
map<int,GIOChannel*> m_ioChannelMap;
map<int,guint> m_ioSourceMap;
- AbstractRoutingEngine *m_engine;
+ AbstractRoutingEngine *m_engine;
struct libwebsocket_protocols protocollist[2];
};
#include <boost/lexical_cast.hpp>
#include <glib.h>
#include <sstream>
-//#include <json-glib/json-glib.h>
#include <listplusplus.h>
#include <timestamp.h>
#include "uuidhelper.h"
#include "debugout.h"
#define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
-libwebsocket_context *context;
+libwebsocket_context *context = NULL;
WebSocketSource *source;
AbstractRoutingEngine *m_re;
char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
new_response+=LWS_SEND_BUFFER_PRE_PADDING;
strcpy(new_response,replystr.c_str());
- libwebsocket_write(clientsocket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
+ if(clientsocket)
+ libwebsocket_write(clientsocket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
}
}
char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
new_response+=LWS_SEND_BUFFER_PRE_PADDING;
strcpy(new_response,replystr.c_str());
- libwebsocket_write(wsi, (unsigned char*)(new_response), strlen(new_response), LWS_WRITE_TEXT);
+ libwebsocket_write(wsi, (unsigned char*)(new_response), strlen(new_response), LWS_WRITE_TEXT);
delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
break;
string type = string(json_object_get_string(typeobject));
- string name = string(json_object_get_string(nameobject));
+ string name = string(json_object_get_string(nameobject));
string id;
json_object_put(valueobject);
json_object_put(timestampobject);
json_object_put(sequenceobject);
-
+
AbstractPropertyType* v = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value);
v->timestamp = boost::lexical_cast<double,std::string>(timestamp);
v->sequence = boost::lexical_cast<double,std::string>(sequence);
{
DebugOut() << "get methodReply has been recieved, without a request being in!. This is likely due to a request coming in after the timeout has elapsed.\n";
}
+
+ delete v;
}
else
{
}
case LWS_CALLBACK_ADD_POLL_FD:
{
- DebugOut(5) << __SMALLFILE__ << ":" << __LINE__ << "Adding poll for websocket IO channel" << endl;
+ DebugOut(5) << __SMALLFILE__ << ":" << __LINE__ << "Adding poll for websocket IO channel" << endl;
//Add a FD to the poll list.
GIOChannel *chan = g_io_channel_unix_new(libwebsocket_get_socket_fd(wsi));
m_sslEnabled = false;
clientConnected = false;
source = this;
- m_re = re;
+ m_re = re;
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
info.protocols = protocols;
std::string uuid = amb::createUuid();
uuidReplyMap[uuid] = reply;
uuidTimeoutMap[uuid] = amb::currentTime() + 10.0; ///TODO: 10 second timeout, make this configurable?
- stringstream s;
+ stringstream s;
s << "{\"type\":\"method\",\"name\":\"get\",\"data\":[\"" << reply->property << "\"],\"transactionid\":\"" << uuid << "\"}";
string replystr = s.str();
char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
new_response+=LWS_SEND_BUFFER_PRE_PADDING;
strcpy(new_response,replystr.c_str());
- libwebsocket_write(clientsocket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
+ if(clientsocket)
+ libwebsocket_write(clientsocket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
}
std::string uuid = amb::createUuid();
uuidRangedReplyMap[uuid] = reply;
uuidTimeoutMap[uuid] = amb::currentTime() + 60; ///TODO: 60 second timeout, make this configurable?
- stringstream s;
+ stringstream s;
s.precision(15);
s << "{\"type\":\"method\",\"name\":\"getRanged\",\"data\": {";
char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
new_response+=LWS_SEND_BUFFER_PRE_PADDING;
strcpy(new_response,replystr.c_str());
- libwebsocket_write(clientsocket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
+ if(clientsocket)
+ libwebsocket_write(clientsocket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
}