static JSBool SMJS_FUNCTION(upnp_service_set_listener) { GPAC_StateVariableListener *svl = NULL; char *name=NULL; u32 i; SMJS_OBJ SMJS_ARGS GPAC_ServiceItem *service = (GPAC_ServiceItem *)SMJS_GET_PRIVATE(c, obj); if (!service || !argc || !JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; if (argc<1) { if (!JSVAL_IS_NULL(service->on_event)) gf_js_remove_root(c, &service->on_event, GF_JSGC_VAL); service->on_event = JSVAL_NULL; if (!JSVAL_IS_NULL(argv[0])) { service->on_event = argv[0]; gf_js_add_root(c, &service->on_event, GF_JSGC_VAL); if (!service->subscribed) { service->m_device->m_pUPnP->m_pGenericController->m_CtrlPoint->Subscribe(service->m_service); service->subscribed = GF_TRUE; } } return JS_TRUE; } if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; name = SMJS_CHARS(c, argv[1]); if (!name) return JS_FALSE; /*variable state listener*/ i=0; while ((svl = (GPAC_StateVariableListener *)gf_list_enum(service->m_StateListeners, &i))) { if (svl->name == (const char *) name) break; } if (!svl) { svl = new GPAC_StateVariableListener(); svl->name = name; svl->var = service->m_service->FindStateVariable(name); gf_list_add(service->m_StateListeners, svl); } if (!JSVAL_IS_NULL(svl->on_event)) gf_js_remove_root(c, &svl->on_event, GF_JSGC_VAL); if (JSVAL_IS_NULL(argv[0])) { gf_list_del_item(service->m_StateListeners, svl); delete svl; } svl->on_event = argv[0]; gf_js_add_root(c, &svl->on_event, GF_JSGC_VAL); if (!service->subscribed) { service->m_device->m_pUPnP->m_pGenericController->m_CtrlPoint->Subscribe(service->m_service); service->subscribed = GF_TRUE; } SMJS_FREE(c, name); return JS_TRUE; }
static JSBool SMJS_FUNCTION(upnp_service_set_action_listener) { PLT_ActionDesc *action; PLT_ArgumentDesc *desc; GPAC_ActionArgListener *argl = NULL; char *name; Bool script_callback = GF_FALSE; u32 i; SMJS_OBJ SMJS_ARGS GPAC_ServiceItem *service = (GPAC_ServiceItem *)SMJS_GET_PRIVATE(c, obj); if (!service || (argc<2) || !JSVAL_IS_STRING(argv[0]) || !JSVAL_IS_OBJECT(argv[1])) return JS_FALSE; name = SMJS_CHARS(c, argv[0]); if (!name) return JS_FALSE; action = service->m_service->FindActionDesc(name); SMJS_FREE(c, name); if (!action) return JS_FALSE; desc = NULL; if (argc==3) { if (JSVAL_IS_BOOLEAN(argv[2])) { script_callback = GF_TRUE; } else { if (!JSVAL_IS_STRING(argv[2]) ) return JS_FALSE; name = SMJS_CHARS(c, argv[2]); if (!name) return JS_FALSE; desc = action->GetArgumentDesc(name); SMJS_FREE(c, name); if (!desc) return JS_FALSE; } } /*action listener*/ i=0; while ((argl = (GPAC_ActionArgListener *)gf_list_enum(service->m_ArgListeners, &i))) { if (argl->arg == desc) break; argl = NULL; } if (!argl) { argl = new GPAC_ActionArgListener(); argl->arg = desc; gf_list_add(service->m_ArgListeners, argl); } argl->action = action; if (!JSVAL_IS_NULL(argl->on_event)) gf_js_remove_root(c, &argl->on_event, GF_JSGC_VAL); if (JSVAL_IS_NULL(argv[1])) { gf_list_del_item(service->m_ArgListeners, argl); delete argl; } argl->on_event = argv[1]; argl->is_script = script_callback; gf_js_add_root(c, &argl->on_event, GF_JSGC_VAL); return JS_TRUE; }
void GPAC_GenericDevice::DetachJS(JSContext *c) { u32 i, count; if (obj) gf_js_remove_root(c, &obj, GF_JSGC_OBJECT); obj = NULL; if (run_proc) gf_js_remove_root(c, &run_proc, GF_JSGC_VAL); run_proc = NULL; if (act_proc) gf_js_remove_root(c, &act_proc, GF_JSGC_VAL); act_proc = NULL; count = gf_list_count(m_pServices); for (i=0; i<count; i++) { GPAC_Service *service = (GPAC_Service*)gf_list_get(m_pServices, i); if (service->m_pObj) { gf_js_remove_root(c, &service->m_pObj, GF_JSGC_OBJECT); service->m_pObj = NULL; } } }
void GPAC_DeviceItem::DetachJS() { if (obj) { gf_js_remove_root(js_ctx, &obj, GF_JSGC_OBJECT); SMJS_SET_PRIVATE(js_ctx, obj, NULL); obj = NULL; } while (gf_list_count(m_Services)) { GPAC_ServiceItem *item = (GPAC_ServiceItem*)gf_list_get(m_Services, 0); gf_list_rem(m_Services, 0); delete item; } }
void GPAC_ServiceItem::DetachJS() { if (obj) { gf_js_remove_root(js_ctx, &obj, GF_JSGC_OBJECT); SMJS_SET_PRIVATE(js_ctx, obj, NULL); obj = NULL; } if (!JSVAL_IS_NULL(on_event)) { gf_js_remove_root(js_ctx, &on_event, GF_JSGC_VAL); on_event = JSVAL_NULL; } while (gf_list_count(m_StateListeners)) { GPAC_StateVariableListener *svl = (GPAC_StateVariableListener *)gf_list_get(m_StateListeners, 0); gf_list_rem(m_StateListeners, 0); gf_js_remove_root(js_ctx, &svl->on_event, GF_JSGC_VAL); delete svl; } while (gf_list_count(m_ArgListeners)) { GPAC_ActionArgListener *argl = (GPAC_ActionArgListener *)gf_list_get(m_ArgListeners, 0); gf_list_rem(m_ArgListeners, 0); gf_js_remove_root(js_ctx, &argl->on_event, GF_JSGC_VAL); delete argl; } }
GPAC_Service::~GPAC_Service() { #ifdef GPAC_HAS_SPIDERMONKEY if (m_pObj) gf_js_remove_root(m_pCtx, &m_pObj, GF_JSGC_OBJECT); #endif }
NPT_Result GPAC_GenericController::OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata) { #ifdef GPAC_HAS_SPIDERMONKEY u32 i, count; GPAC_DeviceItem *item = NULL; GPAC_ServiceItem *serv = NULL; GPAC_ActionArgListener *argl, *act_l; PLT_Service* service = action->GetActionDesc().GetService(); NPT_String uuid; GPAC_ActionUDTA *act_udta = (GPAC_ActionUDTA *)userdata; /*this is NOT an actionResponse to an action triggered on a generic device*/ if (act_udta && act_udta->m_Reserved) act_udta = NULL; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Receive %s Response - error code %d\n", (char *) action->GetActionDesc().GetName(), res)); gf_mx_p(m_ControlPointLock); /*get our device*/ uuid = service->GetDevice()->GetUUID(); count = gf_list_count(m_Devices); for (i=0; i<count; i++) { item = (GPAC_DeviceItem *) gf_list_get(m_Devices, i); if (item->m_UUID == uuid ) { break; } item = NULL; } gf_mx_v(m_ControlPointLock); if (!item) { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Receive %s Response on unknown device (uuid %s)\n", (char *) action->GetActionDesc().GetName(), (char *) uuid)); goto exit; } /*get our service*/ count = gf_list_count(item->m_Services); for (i=0; i<count; i++) { serv = (GPAC_ServiceItem *)gf_list_get(item->m_Services, i); if (serv->m_service == service) break; } if (!serv) { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Receive %s Response on unknown service %s\n", (char *) action->GetActionDesc().GetName(), (char *) service->GetServiceType())); goto exit; } /*locate our listeners*/ act_l = NULL; i=0; while ((argl = (GPAC_ActionArgListener *)gf_list_enum(serv->m_ArgListeners, &i))) { NPT_String value; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] checking argument %s\n", (char *) argl->action->GetName() )); if (argl->action->GetName() != action->GetActionDesc().GetName() ) continue; /*global action listener*/ if (argl->arg==NULL) { act_l = argl; continue; } /*if error don't trigger listeners*/ if (res != NPT_SUCCESS) { GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[UPnP] Receive %s Response: error on remote device %d\n", (char *) action->GetActionDesc().GetName(), res)); continue; } /*action arg listener*/ if (action->GetArgumentValue(argl->arg->GetName(), value) == NPT_SUCCESS) { jsval argv[1], rval; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s argument %s\n", (char *) action->GetActionDesc().GetName(), (char *) argl->arg->GetName() )); m_pUPnP->LockJavascript(GF_TRUE); argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, value) ); JS_CallFunctionValue(serv->js_ctx, serv->obj, argl->on_event, 1, argv, &rval); m_pUPnP->LockJavascript(GF_FALSE); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] %s Response: couldn't get argument %s value\n", (char *) action->GetActionDesc().GetName(), (char *) argl->arg->GetName() )); } } if (act_l) { jsval rval; m_pUPnP->LockJavascript(GF_TRUE); if (act_l->is_script) { JSObject *act_obj; jsval argv[2]; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s\n", (char *) action->GetActionDesc().GetName())); act_obj = JS_NewObject(serv->js_ctx, &item->m_pUPnP->upnpDeviceClass._class, 0, item->obj); SMJS_SET_PRIVATE(serv->js_ctx, act_obj, (void *)action.AsPointer() ); JS_DefineFunction(serv->js_ctx, act_obj, "GetArgumentValue", upnp_action_get_argument_value, 1, 0); JS_DefineFunction(serv->js_ctx, act_obj, "GetErrorCode", upnp_action_get_error_code, 1, 0); JS_DefineFunction(serv->js_ctx, act_obj, "GetError", upnp_action_get_error, 1, 0); gf_js_add_root(serv->js_ctx, &act_obj, GF_JSGC_OBJECT); argv[0] = OBJECT_TO_JSVAL(act_obj); if (act_udta) { argv[1] = act_udta->udta; JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 2, argv, &rval); } else { JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 1, argv, &rval); } gf_js_remove_root(serv->js_ctx, &act_obj, GF_JSGC_OBJECT); } /*if error don't trigger listeners*/ else if (res == NPT_SUCCESS) { GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s\n", (char *) action->GetActionDesc().GetName())); JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 0, 0, &rval); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] response %s has error %d\n", (char *) action->GetActionDesc().GetName(), res )); } m_pUPnP->LockJavascript(GF_FALSE); } GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Done processing response %s\n", (char *) action->GetActionDesc().GetName())); exit: if (act_udta) { gf_js_remove_root(serv->js_ctx, &act_udta->udta, GF_JSGC_VAL); delete act_udta; } return NPT_SUCCESS; #else return NPT_SUCCESS; #endif }