private string Build_SubscribeEvents_Device(string first, CodeProcessor cs, UPnPDevice device, Hashtable serviceNames) { foreach (UPnPService service in device.Services) { bool HasEvent = false; foreach (UPnPStateVariable sv in service.GetStateVariables()) { if (sv.SendEvent) { HasEvent = true; break; } } if (HasEvent) { UPnPDebugObject obj = new UPnPDebugObject(service); string name = (string)obj.GetField("__eventurl"); cs.Append(first + " if (pathlength==" + (name.Length + 1).ToString() + " && memcmp(path+1,\"" + name + "\"," + name.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" " + pc_methodPrefix + "TryToSubscribe(\"" + (string)serviceNames[service] + "\",TimeoutVal,URL,URLLength,session);" + cl); cs.Append(" }" + cl); first = "else"; } } foreach (UPnPDevice d in device.EmbeddedDevices) { first = Build_SubscribeEvents_Device(first, cs, d, serviceNames); } return (first); }
private void BuildHTTPSink_SCPD_HEAD(CodeProcessor cs, UPnPDevice device, Hashtable serviceNames) { UPnPDebugObject obj; foreach (UPnPService service in device.Services) { obj = new UPnPDebugObject(service); string SCPDURL = (string)obj.GetField("SCPDURL"); cs.Append(" else if (header->DirectiveObjLength==" + (SCPDURL.Length + 1).ToString() + " && memcmp((header->DirectiveObj)+1,\"" + SCPDURL + "\"," + SCPDURL.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" " + this.pc_methodLibPrefix + "WebServer_StreamHeader_Raw(session,200,\"OK\",responseHeader,1);" + cl); cs.Append(" " + this.pc_methodLibPrefix + "WebServer_StreamBody(session,NULL,0," + this.pc_methodLibPrefix + "AsyncSocket_MemoryOwnership_STATIC,1);" + cl); cs.Append(" }" + cl); } foreach (UPnPDevice d in device.EmbeddedDevices) { this.BuildHTTPSink_SCPD_HEAD(cs, d, serviceNames); } }
private void BuildHTTPSink_SCPD(CodeProcessor cs, UPnPDevice device, Hashtable serviceNames) { UPnPDebugObject obj; foreach (UPnPService service in device.Services) { obj = new UPnPDebugObject(service); string SCPDURL = (string)obj.GetField("SCPDURL"); cs.Append(" else if (header->DirectiveObjLength==" + (SCPDURL.Length + 1).ToString() + " && memcmp((header->DirectiveObj)+1,\"" + SCPDURL + "\"," + SCPDURL.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); if (this.Configuration.DynamicObjectModel) { cs.Append(" ILibWebServer_StreamHeader_Raw(session,200,\"OK\",responseHeader,1);" + cl); cs.Append(" UPnPStreamDescriptionDocument_SCPD(session,1,NULL,0,0,0,0);" + cl); if (service.Actions.Count > 0) { cs.Append(" buffer = ILibDecompressString((unsigned char*)UPnP_ActionTable_" + serviceNames[service] + "_Impl.Reserved,UPnP_ActionTable_" + serviceNames[service] + "_Impl.ReservedXL,UPnP_ActionTable_" + serviceNames[service] + "_Impl.ReservedUXL);" + cl); foreach (UPnPAction A in service.Actions) { string serviceIdent = DeviceObjectGenerator.GetServiceIdentifier(service); serviceIdent += ("->" + A.Name); cs.Append(" if (" + serviceIdent + "!=NULL){UPnPStreamDescriptionDocument_SCPD(session,0,buffer," + serviceIdent + "->Reserved," + serviceIdent + "->Reserved2,0,0);}" + cl); } cs.Append(" free(buffer);" + cl); } cs.Append(" UPnPStreamDescriptionDocument_SCPD(session,0,NULL,0,0,1,0);" + cl); if (service.GetStateVariables().Length > 0) { cs.Append(" buffer = ILibDecompressString((unsigned char*)UPnP_StateVariableTable_" + serviceNames[service] + "_Impl.Reserved,UPnP_StateVariableTable_" + serviceNames[service] + "_Impl.ReservedXL,UPnP_StateVariableTable_" + serviceNames[service] + "_Impl.ReservedUXL);" + cl); foreach (UPnPStateVariable V in service.GetStateVariables()) { string vIdent = DeviceObjectGenerator.GetStateVariableIdentifier(V); cs.Append(" if (" + vIdent + "!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved1," + vIdent + "->Reserved1L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); if (V.Minimum != null || V.Maximum != null) { cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved4," + vIdent + "->Reserved4L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" if (" + vIdent + "->MinMaxStep[0]!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"<minimum>\",9,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session," + vIdent + "->MinMaxStep[0],(int)strlen(" + vIdent + "->MinMaxStep[0]),ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"</minimum>\",10,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" }" + cl); cs.Append(" if (" + vIdent + "->MinMaxStep[1]!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"<maximum>\",9,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session," + vIdent + "->MinMaxStep[1],(int)strlen(" + vIdent + "->MinMaxStep[1]),ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"</maximum>\",10,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" }" + cl); cs.Append(" if (" + vIdent + "->MinMaxStep[2]!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"<step>\",6,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session," + vIdent + "->MinMaxStep[2],(int)strlen(" + vIdent + "->MinMaxStep[2]),ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"</step>\",7,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" }" + cl); cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved5," + vIdent + "->Reserved5L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); } if (V.DefaultValue != null) { cs.Append(" if (" + vIdent + "->DefaultValue!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved6," + vIdent + "->Reserved6L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session," + vIdent + "->DefaultValue,(int)strlen(" + vIdent + "->DefaultValue),ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved7," + vIdent + "->Reserved7L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" }" + cl); } if (V.AllowedStringValues != null) { cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved2," + vIdent + "->Reserved2L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" for(i=0;i<UPnP_StateVariable_AllowedValues_MAX;++i)" + cl); cs.Append(" {" + cl); cs.Append(" if (" + vIdent + "->AllowedValues[i]!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"<allowedValue>\",14,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session," + vIdent + "->AllowedValues[i],(int)strlen(" + vIdent + "->AllowedValues[i]),ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" ILibWebServer_StreamBody(session,\"</allowedValue>\",15,ILibAsyncSocket_MemoryOwnership_STATIC,0);" + cl); cs.Append(" }" + cl); cs.Append(" }" + cl); cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved3," + vIdent + "->Reserved3L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); } cs.Append(" ILibWebServer_StreamBody(session,buffer+" + vIdent + "->Reserved8," + vIdent + "->Reserved8L,ILibAsyncSocket_MemoryOwnership_USER,0);" + cl); cs.Append(" }" + cl); } cs.Append(" free(buffer);" + cl); } cs.Append(" UPnPStreamDescriptionDocument_SCPD(session,0,NULL,0,0,0,1);" + cl); } else { cs.Append(" buffer = " + this.pc_methodLibPrefix + "DecompressString((unsigned char*)" + pc_methodPrefix + serviceNames[service] + "Description," + pc_methodPrefix + serviceNames[service] + "DescriptionLength," + pc_methodPrefix + serviceNames[service] + "DescriptionLengthUX);" + cl); cs.Append(" " + this.pc_methodLibPrefix + "WebServer_Send_Raw(session,buffer," + pc_methodPrefix + serviceNames[service] + "DescriptionLengthUX,0,1);" + cl); } cs.Append(" }" + cl); } foreach (UPnPDevice d in device.EmbeddedDevices) { this.BuildHTTPSink_SCPD(cs, d, serviceNames); } }
private string BuildHTTPSink_CONTROL(CodeProcessor cs, UPnPDevice device, Hashtable serviceNames, string f1) { UPnPDebugObject obj; string first1 = f1; foreach (UPnPService service in device.Services) { obj = new UPnPDebugObject(service); string CONTROLURL = (string)obj.GetField("__controlurl"); cs.Append(" " + first1 + " if (header->DirectiveObjLength==" + (CONTROLURL.Length + 1).ToString() + " && memcmp((header->DirectiveObj)+1,\"" + CONTROLURL + "\"," + CONTROLURL.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); string first2 = ""; foreach (UPnPAction action in service.Actions) { cs.Append(" " + first2 + " if (SOAPACTIONLength==" + action.Name.Length.ToString() + " && memcmp(SOAPACTION,\"" + action.Name + "\"," + action.Name.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" " + pc_methodPrefix + "Dispatch_" + (string)serviceNames[service] + "_" + action.Name + "(bodyBuffer, offset, bodyBufferLength, session);" + cl); cs.Append(" }" + cl); first2 = "else"; } if (service.Actions.Count > 0) { cs.Append(" else" + cl); cs.Append(" {" + cl); } cs.Append(" RetVal=1;" + cl); if (service.Actions.Count > 0) { cs.Append(" }" + cl); } cs.Append(" }" + cl); first1 = "else"; } // if (device.Services.Length>0) // { // cs.Append(" else"+cl); // cs.Append(" {"+cl); // cs.Append(" RetVal=1;"+cl); // cs.Append(" }"+cl); // } foreach (UPnPDevice d in device.EmbeddedDevices) { first1 = this.BuildHTTPSink_CONTROL(cs, d, serviceNames, first1); } return (first1); }
protected bool GenerateEx(UPnPDevice device, DirectoryInfo outputDirectory, Hashtable serviceNames, ref string SampleApp) { bool BuildSampleApp = SampleApp == null ? false : true; ServiceGenerator.Configuration DeviceConf = (ServiceGenerator.Configuration)device.User; #region Initialize string WS; StreamWriter W; Hashtable ChoTable = new Hashtable(); Hashtable SeqTable = new Hashtable(); int SequenceCounter = 0; int ChoiceCounter = 0; string first = ""; RootDevice = device; SortedList SL = new SortedList(); IDictionaryEnumerator en = serviceNames.GetEnumerator(); while (en.MoveNext()) { SL[en.Value] = en.Key; } en = SL.GetEnumerator(); if (this.SubTarget == SUBTARGETS.NONE) { UseSystem = this.Platform.ToString(); } else { UseSystem = this.SubTarget.ToString(); } pc_methodPrefix = ((ServiceGenerator.Configuration)device.User).Prefix; pc_methodLibPrefix = Configuration.prefixlib; if (this.Language == LANGUAGES.C) { pc_methodPrefixDef = CallingConvention + pc_methodPrefix; pc_classPrefix = ""; } if (this.Language == LANGUAGES.CPP) { pc_methodPrefixDef = CallingConvention + ClassName + "::" + pc_methodPrefix; pc_classPrefix = ClassName + "::"; } AllServices.Clear(); AddAllServices(device); FriendlyNameTable.Clear(); Fix(device, 0, serviceNames); PrivateClassDeclarations = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); PublicClassDeclarations = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); CodeProcessor cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.NewLine = this.CodeNewLine; cs.ClassDefinitions = PrivateClassDeclarations; cs.PublicClassDefinitions = PublicClassDeclarations; PrivateClassDeclarations.CodeTab = Indent; PublicClassDeclarations.CodeTab = Indent; cs.CodeTab = Indent; #endregion #region New Style UPnPMicroStack.h WS = SourceCodeRepository.GetMicroStack_H_Template(pc_methodPrefix); #region UPnP/1.1 Complex Types cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildComplexTypeDefinitionsAndHeaders(SL, cs, SeqTable, ChoTable, ref SequenceCounter, ref ChoiceCounter, this.pc_methodPrefix, this.pc_methodLibPrefix); WS = WS.Replace("//{{{ComplexTypeCode}}}", cs.ToString()); #endregion #region Function Callbacks cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en.Reset(); while (en.MoveNext()) { UPnPService service = (UPnPService)en.Value; foreach (UPnPAction action in service.Actions) { cs.Append(" typedef void(*UPnP_ActionHandler_" + serviceNames[service] + "_" + action.Name + ") (void* upnptoken"); foreach (UPnPArgument args in action.Arguments) { if (args.Direction == "in") { if (args.RelatedStateVar.ComplexType == null) { cs.Append("," + ToCType(args.RelatedStateVar.GetNetType().FullName) + " " + args.Name); if (args.RelatedStateVar.GetNetType().FullName == "System.Byte[]") { cs.Append(",int _" + args.Name + "Length"); } } else { // Complex Type cs.Append(", struct " + args.RelatedStateVar.ComplexType.Name_LOCAL + " *" + args.Name); } } } cs.Append(");" + cl); } } en.Reset(); while (en.MoveNext()) { UPnPService service = (UPnPService)en.Value; if (Configuration.EXTERN_Callbacks == true || serviceNames[service].ToString() == "DeviceSecurity") { foreach (UPnPAction action in service.Actions) { if (serviceNames[service].ToString() == "DeviceSecurity") { cs.Append("extern void " + pc_methodLibPrefix + serviceNames[service] + "_" + action.Name + "(void* upnptoken"); } else { cs.Append("extern void " + pc_methodPrefix + serviceNames[service] + "_" + action.Name + "(void* upnptoken"); } foreach (UPnPArgument arg in action.Arguments) { if (arg.Direction == "in") { cs.Append("," + ToCType(arg.RelatedStateVar.GetNetType().ToString()) + " " + arg.Name); if (arg.RelatedStateVar.GetNetType().FullName == "System.Byte[]") { cs.Append(",int _" + arg.Name + "Length"); } } } cs.Append(");" + cl); } } } if (Configuration.EXTERN_Callbacks == false) { cs.Comment("UPnP Set Function Pointers Methods"); cs.Append("extern void (*" + pc_methodPrefixDef + "FP_PresentationPage) (void* upnptoken,struct packetheader *packet);" + cl); BuildFunctionPointerHeaders(cs, device, serviceNames); cs.Append(cl); } else { cs.Append("extern void " + pc_methodPrefix + "PresentationRequest(void* upnptoken, struct packetheader *packet);" + cl); } WS = WS.Replace("//{{{UPnP_Set_Function_Pointer_Methods}}}", cs.ToString()); #endregion #region Invocation Response Methods cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Comment("Invocation Response Methods"); cs.Append("void " + pc_methodPrefixDef + "Response_Error(const UPnPSessionToken UPnPToken, const int ErrorCode, const char* ErrorMsg);" + cl); cs.Append("void " + pc_methodPrefixDef + "ResponseGeneric(const UPnPSessionToken UPnPToken,const char* ServiceURI,const char* MethodName,const char* Params);" + cl); if (ServiceGenerator.ServiceConfiguration.HasFragmentedActions(device)) { cs.Append("int " + pc_methodPrefixDef + "AsyncResponse_START(const UPnPSessionToken UPnPToken, const char* actionName, const char* serviceUrnWithVersion);" + cl); cs.Append("int " + pc_methodPrefixDef + "AsyncResponse_DONE(const UPnPSessionToken UPnPToken, const char* actionName);" + cl); cs.Append("int " + pc_methodPrefixDef + "AsyncResponse_OUT(const UPnPSessionToken UPnPToken, const char* outArgName, const char* bytes, const int byteLength, enum ILibAsyncSocket_MemoryOwnership bytesMemoryOwnership,const int startArg, const int endArg);" + cl); } BuildUPnPResponseHeaders(cs, device, serviceNames); WS = WS.Replace("//{{{Invocation_Response_Methods}}}", cs.ToString()); #endregion #region Eventing Methods cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Comment("State Variable Eventing Methods"); BuildStateVariableHeaders(cs, device, serviceNames); WS = WS.Replace("//{{{Eventing_Methods}}}", cs.ToString()); #endregion #region Multicast Eventing Methods if (device.ArchitectureVersion != "1.0") { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Comment("State Variable Multicast-Eventing Methods"); BuildMulticastStateVariableHeaders(cs, device, serviceNames); WS = WS.Replace("//{{{MulticastEventing_Methods}}}", cs.ToString()); WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_MulticastEventing}}}", "//{{{END_MulticastEventing}}}", WS); WS = BuildMulticastStateVariableHeaders2(WS, device, serviceNames); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_MulticastEventing_Specific}}}", "//{{{END_MulticastEventing_Specific}}}", WS); } else { WS = WS.Replace("//{{{MulticastEventing_Methods}}}", ""); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_MulticastEventing}}}", "//{{{END_MulticastEventing}}}", WS); } #endregion #region CreateMicroStack Definition cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append("UPnPMicroStackToken UPnPCreateMicroStack(void *Chain, "); BuildCreateMicroStackDefinition(cs, device, 1); cs.Append("const char* UDN, const char* SerialNumber, const int NotifyCycleSeconds, const unsigned short PortNum);" + cl); WS = WS.Replace("//{{{CreateMicroStackHeader}}}", cs.ToString()); #endregion #region Device Object Model if (this.Configuration.DynamicObjectModel) { WS = WS.Replace("//{{{ObjectDefintions}}}", DeviceObjectGenerator.GetDeviceObjectsString(device)); WS = WS.Replace("//{{{GetConfiguration}}}", "struct UPnP_Device_" + device.User2.ToString() + "* UPnPGetConfiguration();" + cl); } else { WS = WS.Replace("//{{{ObjectDefintions}}}", ""); WS = WS.Replace("//{{{GetConfiguration}}}", ""); } #endregion #region Prefixes WS = WS.Replace("UPnP", this.pc_methodPrefix); WS = WS.Replace("ILib", this.pc_methodLibPrefix); #endregion #region Write to disk W = File.CreateText(outputDirectory.FullName + "\\" + pc_methodPrefix + "MicroStack.h"); W.Write(WS); W.Close(); #endregion #endregion #region New Style UPnPMicroStack.c WS = SourceCodeRepository.GetMicroStack_C_Template(pc_methodPrefix); #region Set Function Pointers if (Configuration.EXTERN_Callbacks == false) { cs.Comment("UPnP Set Function Pointers Methods"); string staticdef = ""; if (this.Language == LANGUAGES.CPP) staticdef = "static "; cs.Append("void (*" + pc_methodPrefixDef + "FP_PresentationPage) (void* upnptoken,struct packetheader *packet);" + cl); cs.PublicClassDefinitions.Append(staticdef + "void (*" + pc_methodPrefix + "FP_PresentationPage) (void* upnptoken,struct packetheader *packet);" + cl); BuildFunctionPointers(cs, device, serviceNames); cs.Append(cl); WS = WS.Replace("//{{{FunctionPointers}}}", cs.ToString()); } else { WS = WS.Replace("//{{{FunctionPointers}}}", ""); } #endregion #region Build and Compress Device Description //Compress Device Description cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildDeviceDescription(cs, device); BuildServiceDescriptions(cs, device, serviceNames); WS = WS.Replace("//{{{CompressedDescriptionDocs}}}", cs.ToString()); #endregion #region Object Model if (this.Configuration.DynamicObjectModel) { WS = WS.Replace("//{{{ObjectDefintions}}}", DeviceObjectGenerator.GetPopulatedDeviceObjectsString(device)); WS = DeviceObjectGenerator.BuildDeviceDescriptionStreamer(device, WS); WS = SourceCodeRepository.RemoveTag("//{{{Device_Object_Model_BEGIN}}}", "//{{{Device_Object_Model_END}}}", WS); WS = SourceCodeRepository.RemoveAndClearTag("//{{{Device_Default_Model_BEGIN}}}", "//{{{Device_Default_Model_END}}}", WS); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append("struct UPnP_Device_" + device.User2.ToString() + "* UPnPGetConfiguration()" + cl); cs.Append("{" + cl); cs.Append(" return(&(" + DeviceObjectGenerator.GetDeviceIdentifier(device) + "));" + cl); cs.Append("}" + cl); WS = WS.Replace("//{{{GetConfiguration}}}", cs.ToString()); } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{Device_Object_Model_BEGIN}}}", "//{{{Device_Object_Model_END}}}", WS); WS = SourceCodeRepository.RemoveTag("//{{{Device_Default_Model_BEGIN}}}", "//{{{Device_Default_Model_END}}}", WS); WS = WS.Replace("//{{{GetConfiguration}}}", ""); } #endregion #region FragmentedResponseSystem if (ServiceGenerator.ServiceConfiguration.HasFragmentedActions(device)) { WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_FragmentedResponseSystem}}}", "//{{{END_FragmentedResponseSystem}}}", WS); } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_FragmentedResponseSystem}}}", "//{{{END_FragmentedResponseSystem}}}", WS); } #endregion #region CreateMicroStackDefinition cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append("UPnPMicroStackToken UPnPCreateMicroStack(void *Chain, "); BuildCreateMicroStackDefinition(cs, device, 1); cs.Append("const char* UDN, const char* SerialNumber, const int NotifyCycleSeconds, const unsigned short PortNum)" + cl); WS = WS.Replace("//{{{CreateMicroStackDefinition}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" RetVal->DeviceDescriptionLength = snprintf(RetVal->DeviceDescription, len, DDT"); if (device.ArchitectureVersion != "1.0") { cs.Append(", RetVal->ConfigID"); } BuildCreateMicroStackDefinition_sprintf(cs, device, 1); cs.Append(");" + cl); WS = WS.Replace("//{{{CreateMicroStack_sprintf}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" len = 10 + UPnPDeviceDescriptionTemplateLengthUX"); int nd = BuildCreateMicroStackDefinition_Malloc(cs, device, 1); cs.Append(" + (((int)strlen(RetVal->Serial) + (int)strlen(RetVal->UUID)) * " + nd.ToString() + ");" + cl); cs.Append(" if ((RetVal->DeviceDescription = (char*)malloc(len)) == NULL) ILIBCRITICALEXIT(254);" + cl); WS = WS.Replace("//{{{DeviceDescriptionMalloc}}}", cs.ToString()); if (nd == 1) { WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_EmbeddedDevice>0}}}", "//{{{END_EmbeddedDevices>0}}}", WS); WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_EmbeddedDevices=0}}}", "//{{{END_EmbeddedDevices=0}}}", WS); } else { WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_EmbeddedDevice>0}}}", "//{{{END_EmbeddedDevices>0}}}", WS); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_EmbeddedDevices=0}}}", "//{{{END_EmbeddedDevices=0}}}", WS); } #endregion #region CreateMicroStack --> Object Meta Data if (Configuration.DynamicObjectModel) { cs = new CodeProcessor(new StringBuilder(), false); BuildObjectMetaData(cs, device, 1); WS = WS.Replace("//{{{ObjectModel_MetaData}}}", cs.ToString()); } else { WS = WS.Replace("//{{{ObjectModel_MetaData}}}", ""); } #endregion #region Presentation Page Support cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); if (DeviceConf.AdvertisesPresentationPage) { cs.Append("/* Presentation Page Support */" + cl); cs.Append("if (header->DirectiveObjLength>=4 && memcmp(header->DirectiveObj,\"/web\",4)==0)" + cl); cs.Append("{" + cl); if (Configuration.EXTERN_Callbacks) { cs.Append(" UPnPPresentationRequest((void*)session,header);" + cl); } else { cs.Append(" UPnPFP_PresentationPage((void*)session,header);" + cl); } cs.Append("}" + cl); cs.Append("else "); } WS = WS.Replace("//{{{PRESENTATIONPAGE}}}", cs.ToString()); #endregion #region #define vs method definition, on SSDP related stuff (Embedded Devices) if (this.GetNumberOfTotalEmbeddedDevices(device) == 0) { // No Embedded Devices WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_EmbeddedDevices=0}}}", "//{{{END_EmbeddedDevices=0}}}", WS); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_EmbeddedDevices>0}}}", "//{{{END_EmbeddedDevices>0}}}", WS); } else { // There are Embedded Devices WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_EmbeddedDevices=0}}}", "//{{{END_EmbeddedDevices=0}}}", WS); WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_EmbeddedDevices>0}}}", "//{{{END_EmbeddedDevices>0}}}", WS); } #endregion #region ssdp:all cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildSSDPALL_Response(device, cs, 0); WS = WS.Replace("//{{{SSDP:ALL}}}", cs.ToString()); #endregion #region ssdp:other if (DoesDeviceHaveAnyNonVersionOneComponents(device)) { WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_VERSION>1}}}", "//{{{END_VERSION>1}}}", WS); } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_VERSION>1}}}", "//{{{END_VERSION>1}}}", WS); } cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildMSEARCHHandler_device(device, cs, 0); WS = WS.Replace("//{{{SSDP:OTHER}}}", cs.ToString()); #endregion #region FragmentedSendNotify Case statements cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" case 1:" + cl); cs.Append(" " + this.pc_methodPrefix + "BuildSendSsdpNotifyPacket(FNS->upnp->NOTIFY_SEND_socks[i], FNS->upnp, (struct sockaddr*)&(FNS->upnp->AddressListV4[i]), 0, \"::upnp:rootdevice\", \"upnp:rootdevice\", \"\");" + cl); cs.Append(" break;" + cl); BuildFragmentedNotify_CaseStatement(cs, device, 2, 0, false); WS = WS.Replace("//{{{FragmentedSendNotifyCaseStatements}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" case 1:" + cl); cs.Append(" " + this.pc_methodPrefix + "BuildSendSsdpNotifyPacket(FNS->upnp->NOTIFY_SEND_socks6[i], FNS->upnp, (struct sockaddr*)&(FNS->upnp->AddressListV6[i]), 0, \"::upnp:rootdevice\", \"upnp:rootdevice\", \"\");" + cl); cs.Append(" break;" + cl); BuildFragmentedNotify_CaseStatement(cs, device, 2, 0, true); WS = WS.Replace("//{{{FragmentedSendNotifyV6CaseStatements}}}", cs.ToString()); #endregion #region SendNotify "For statement" cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" " + pc_methodPrefix + "BuildSendSsdpNotifyPacket(upnp->NOTIFY_SEND_socks[i], upnp, (struct sockaddr*)&(upnp->AddressListV4[i]), 0, \"::upnp:rootdevice\", \"upnp:rootdevice\", \"\");" + cl); BuildNotifyPackets_Device(cs, device, 0, false); WS = WS.Replace("//{{{SendNotifyForStatement}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" " + pc_methodPrefix + "BuildSendSsdpNotifyPacket(upnp->NOTIFY_SEND_socks6[i], upnp, (struct sockaddr*)&(upnp->AddressListV6[i]), 0, \"::upnp:rootdevice\", \"upnp:rootdevice\", \"\");" + cl); BuildNotifyPackets_Device(cs, device, 0, true); WS = WS.Replace("//{{{SendNotifyV6ForStatement}}}", cs.ToString()); WS = WS.Replace("!NUMPACKETS!", this.CountPackets(device).ToString()); #endregion #region SendByeBye "For statement" cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" " + pc_methodPrefix + "BuildSendSsdpByeByePacket(upnp->NOTIFY_SEND_socks[i], upnp, (struct sockaddr*)&(upnp->MulticastAddrV4), UPNP_MCASTv4_GROUP, \"::upnp:rootdevice\", \"upnp:rootdevice\", \"\", 0);" + cl); BuildByeByePackets_Device(cs, device, 0, false); WS = WS.Replace("//{{{SendByeByeForStatement}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append(" " + pc_methodPrefix + "BuildSendSsdpByeByePacket(upnp->NOTIFY_SEND_socks6[i], upnp, t1, t2, \"::upnp:rootdevice\", \"upnp:rootdevice\", \"\", 0);" + cl); BuildByeByePackets_Device(cs, device, 0, true); WS = WS.Replace("//{{{SendByeByeV6ForStatement}}}", cs.ToString()); #endregion #region Device Icon if (device.Icon != null) { WS = SourceCodeRepository.RemoveTag("//{{{DeviceIcon_Begin}}}", "//{{{DeviceIcon_End}}}", WS); string iconString; MemoryStream ms = new MemoryStream(); device.Icon.Save(ms, System.Drawing.Imaging.ImageFormat.Png); HTTPMessage r; if (Configuration.HTTP_1dot1) { r = new HTTPMessage("1.1"); } else { r = new HTTPMessage("1.0"); } r.StatusCode = 200; r.StatusData = "OK"; r.ContentType = "image/png"; r.BodyBuffer = ms.ToArray(); // Small PNG DeviceObjectGenerator.InjectBytes(out iconString, r.RawPacket, this.CodeNewLine, false); WS = WS.Replace("{{{IconLength_SMPNG}}}", r.RawPacket.Length.ToString()); WS = WS.Replace("{{{IconLength_HEAD_SMPNG}}}", (r.RawPacket.Length - r.BodyBuffer.Length).ToString()); WS = WS.Replace("{{{ICON_SMPNG}}}", iconString); // Small JPG ms = new MemoryStream(); device.Icon.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); r.ContentType = "image/jpg"; r.BodyBuffer = ms.ToArray(); DeviceObjectGenerator.InjectBytes(out iconString, r.RawPacket, this.CodeNewLine, false); WS = WS.Replace("{{{IconLength_SMJPG}}}", r.RawPacket.Length.ToString()); WS = WS.Replace("{{{IconLength_HEAD_SMJPG}}}", (r.RawPacket.Length - r.BodyBuffer.Length).ToString()); WS = WS.Replace("{{{ICON_SMJPG}}}", iconString); if (device.Icon2 != null) { // Large PNG ms = new MemoryStream(); device.Icon2.Save(ms, System.Drawing.Imaging.ImageFormat.Png); r.ContentType = "image/png"; r.BodyBuffer = ms.ToArray(); DeviceObjectGenerator.InjectBytes(out iconString, r.RawPacket, this.CodeNewLine, false); WS = WS.Replace("{{{IconLength_LGPNG}}}", r.RawPacket.Length.ToString()); WS = WS.Replace("{{{IconLength_HEAD_LGPNG}}}", (r.RawPacket.Length - r.BodyBuffer.Length).ToString()); WS = WS.Replace("{{{ICON_LGPNG}}}", iconString); // Large JPG ms = new MemoryStream(); device.Icon2.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); r.ContentType = "image/jpg"; r.BodyBuffer = ms.ToArray(); DeviceObjectGenerator.InjectBytes(out iconString, r.RawPacket, this.CodeNewLine, false); WS = WS.Replace("{{{IconLength_LGJPG}}}", r.RawPacket.Length.ToString()); WS = WS.Replace("{{{IconLength_HEAD_LGJPG}}}", (r.RawPacket.Length - r.BodyBuffer.Length).ToString()); WS = WS.Replace("{{{ICON_LGJPG}}}", iconString); } } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{DeviceIcon_Begin}}}", "//{{{DeviceIcon_End}}}", WS); } #endregion #region Dispatch Methods cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); Build_DispatchMethods(cs, serviceNames); WS = WS.Replace("//{{{DispatchMethods}}}", cs.ToString()); #endregion #region Dispatch Controller cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); if (BuildHTTPSink_CONTROL(cs, device, serviceNames, "") != "") { cs.Append(" else" + cl); cs.Append(" {" + cl); cs.Append(" RetVal=1;" + cl); cs.Append(" }" + cl); } else { cs.Append(" RetVal=1;" + cl); } WS = WS.Replace("//{{{DispatchControl}}}", cs.ToString()); #endregion #region Invocation Response Methods cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildUPnPResponse(cs, device, serviceNames); WS = WS.Replace("//{{{InvokeResponseMethods}}}", cs.ToString()); #endregion #region GetInitialEventBody cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildEventHelpers_InitialEvent(cs, serviceNames); WS = WS.Replace("//{{{InitialEventBody}}}", cs.ToString()); #endregion #region Multicast Events if (device.ArchitectureVersion != "1.0") { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildMulticastSoapEvents(cs, device, serviceNames); WS = WS.Replace("//{{{SetStateMethods}}}", "//{{{SetStateMethods}}}\r\n" + cs.ToString()); WS = BuildMulticastSoapEventsProcessor(WS, device, serviceNames); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_CHECK_MULTICASTVARIABLE}}}", "//{{{END_CHECK_MULTICASTVARIABLE}}}", WS); WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_MulticastEventing}}}", "//{{{END_MulticastEventing}}}", WS); WS = WS.Replace("{{{VARDEFS}}}", ""); } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_MulticastEventing}}}", "//{{{END_MulticastEventing}}}", WS); } #endregion #region SetState Methods cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildSoapEvents(cs, device, serviceNames); WS = WS.Replace("//{{{SetStateMethods}}}", cs.ToString()); #endregion #region UnSubscribeDispatcher string packet = "HTTP/!HTTPVERSION! %d %s\\r\\nContent-Length: 0\\r\\n\\r\\n"; cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); first = ""; en.Reset(); while (en.MoveNext()) { UPnPService service = (UPnPService)en.Value; UPnPDebugObject obj = new UPnPDebugObject(service); string name = (string)obj.GetField("__eventurl"); cs.Append(" " + first + "if (header->DirectiveObjLength==" + (name.Length + 1).ToString() + " && memcmp(header->DirectiveObj + 1,\"" + name + "\"," + name.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" Info = " + pc_methodPrefix + "RemoveSubscriberInfo(&(((struct " + pc_methodPrefix + "DataObject*)session->User)->HeadSubscriberPtr_" + (string)en.Key + "),&(((struct " + pc_methodPrefix + "DataObject*)session->User)->NumberOfSubscribers_" + (string)en.Key + "),SID,SIDLength);" + cl); cs.Append(" if (Info != NULL)" + cl); cs.Append(" {" + cl); cs.Append(" --Info->RefCount;" + cl); cs.Append(" if (Info->RefCount == 0)" + cl); cs.Append(" {" + cl); cs.Append(" " + pc_methodPrefix + "DestructSubscriberInfo(Info);" + cl); cs.Append(" }" + cl); cs.Append(" packetlength = snprintf(packet, 50, \"" + packet + "\", 200, \"OK\");" + cl); cs.Append(" " + this.pc_methodLibPrefix + "WebServer_Send_Raw(session, packet, packetlength, 0, 1);" + cl); cs.Append(" }" + cl); cs.Append(" else" + cl); cs.Append(" {" + cl); cs.Append(" packetlength = snprintf(packet, 50, \"" + packet + "\", 412, \"Invalid SID\");" + cl); cs.Append(" " + this.pc_methodLibPrefix + "WebServer_Send_Raw(session, packet, packetlength, 0, 1);" + cl); cs.Append(" }" + cl); cs.Append(" }" + cl); first = "else "; } WS = WS.Replace("//{{{UnSubscribeDispatcher}}}", cs.ToString()); #endregion #region SubscribeDispatcher cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); first = Build_SubscribeEvents_Device("", cs, device, serviceNames); if (first != "") { cs.Append(" else" + cl); cs.Append(" {" + cl); cs.Append(" " + this.pc_methodLibPrefix + "WebServer_Send_Raw(session,\"HTTP/1.1 412 Invalid Service Name\\r\\nContent-Length: 0\\r\\n\\r\\n\",56,1,1);" + cl); cs.Append(" }" + cl); } else { cs.Append(" " + this.pc_methodLibPrefix + "WebServer_Send_Raw(session,\"HTTP/1.1 412 Invalid Service Name\\r\\nContent-Length: 0\\r\\n\\r\\n\",56,1,1);" + cl); } WS = WS.Replace("//{{{SubscribeEventsDispatcher}}}", cs.ToString()); #endregion #region Maximum Subscription Timeout WS = WS.Replace("{{{UPnP_MAX_SUBSCRIPTION_TIMEOUT}}}", ((ServiceGenerator.Configuration)device.User).MaxSubscriptionTimeout.ToString()); #endregion #region State Variables cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); while (en.MoveNext()) { string name = (string)en.Key; UPnPService s = (UPnPService)en.Value; foreach (UPnPStateVariable v in s.GetStateVariables()) { if (v.SendEvent) { cs.Append(" char* " + name + "_" + v.Name + ";" + cl); } if (v.MulticastEvent) { cs.Append(" int " + name + "_" + v.Name + "_SEQ;" + cl); } } } WS = WS.Replace("//{{{StateVariables}}}", cs.ToString()); #endregion #region Subscriber Head Pointer cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); while (en.MoveNext()) { string name = (string)en.Key; cs.Append(" struct SubscriberInfo *HeadSubscriberPtr_" + name + ";" + cl); cs.Append(" int NumberOfSubscribers_" + name + ";" + cl); } WS = WS.Replace("//{{{HeadSubscriberPointers}}}", cs.ToString()); #endregion #region UPnPExpireSubscriberInfo cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); first = ""; while (en.MoveNext()) { string name = (string)en.Key; cs.Append(" " + first + "if (d->HeadSubscriberPtr_" + name + "==t)" + cl); cs.Append(" {" + cl); cs.Append(" --(d->NumberOfSubscribers_" + name + ");" + cl); cs.Append(" }" + cl); first = "else "; } WS = WS.Replace("//{{{UPnPExpireSubscriberInfo1}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); first = ""; while (en.MoveNext()) { string name = (string)en.Key; cs.Append(" " + first + "if (d->HeadSubscriberPtr_" + name + "==info)" + cl); cs.Append(" {" + cl); cs.Append(" d->HeadSubscriberPtr_" + name + " = info->Next;" + cl); cs.Append(" if (info->Next!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" info->Next->Previous = NULL;" + cl); cs.Append(" }" + cl); cs.Append(" }" + cl); first = "else "; } cs.Append(" " + first + cl); if (first != "") { cs.Append(" {" + cl); } cs.Append(" // Error" + cl); cs.Append(" return;" + cl); if (first != "") { cs.Append(" }" + cl); } WS = WS.Replace("//{{{UPnPExpireSubscriberInfo2}}}", cs.ToString()); #endregion #region TryToSubscribe HeadPointer Initializer cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); while (en.MoveNext()) { string name = (string)en.Key; cs.Append(" if (strncmp(ServiceName,\"" + name + "\"," + name.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" TotalSubscribers = &(dataObject->NumberOfSubscribers_" + name + ");" + cl); cs.Append(" HeadPtr = &(dataObject->HeadSubscriberPtr_" + name + ");" + cl); cs.Append(" }" + cl); } WS = WS.Replace("//{{{SubscribeHeadPointerInitializer}}}", cs.ToString()); #endregion #region TryToSubscribe Initial Event cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); first = ""; while (en.MoveNext()) { string name = (string)en.Key; UPnPService s = (UPnPService)en.Value; bool HasEvents = false; foreach (UPnPStateVariable v in s.GetStateVariables()) { if (v.SendEvent) { HasEvents = true; break; } } if (HasEvents) { cs.Append(" " + first + "if (strcmp(ServiceName,\"" + name + "\")==0)" + cl); cs.Append(" {" + cl); cs.Append(" UPnPGetInitialEventBody_" + name + "(dataObject,&packetbody,&packetbodyLength);" + cl); cs.Append(" }" + cl); first = "else "; } } WS = WS.Replace("//{{{TryToSubscribe_InitialEvent}}}", cs.ToString()); #endregion #region Subscription Renewal HeadPointer Initializer cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); first = ""; en.Reset(); while (en.MoveNext()) { UPnPService service = (UPnPService)en.Value; UPnPDebugObject obj = new UPnPDebugObject(service); string name = (string)obj.GetField("__eventurl"); string sname = (string)en.Key; cs.Append(first + " if (pathlength==" + (name.Length + 1).ToString() + " && memcmp(path+1,\"" + name + "\"," + name.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" info = ((struct " + this.pc_methodPrefix + "DataObject*)ReaderObject->User)->HeadSubscriberPtr_" + sname + ";" + cl); cs.Append(" }" + cl); first = "else"; } WS = WS.Replace("//{{{RenewHeadInitializer}}}", cs.ToString()); #endregion #region SendEvent HeadPointer Initializer cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en.Reset(); while (en.MoveNext()) { string name = (string)en.Key; cs.Append(" if (strncmp(eventname,\"" + name + "\"," + name.Length.ToString() + ")==0)" + cl); cs.Append(" {" + cl); cs.Append(" info = UPnPObject->HeadSubscriberPtr_" + name + ";" + cl); cs.Append(" }" + cl); } WS = WS.Replace("//{{{SendEventHeadPointerInitializer}}}", cs.ToString()); #endregion #region HeadDispatcher cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildHTTPSink_SCPD_HEAD(cs, device, serviceNames); WS = WS.Replace("//{{{HeadDispatcher}}}", cs.ToString()); #endregion #region GetDispatcher cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildHTTPSink_SCPD(cs, device, serviceNames); WS = WS.Replace("//{{{GetDispatcher}}}", cs.ToString()); if (DeviceObjectGenerator.CalculateMaxAllowedValues(device, 0) != 0) { WS = SourceCodeRepository.RemoveTag("//{{{HASALLOWEDVALUES_BEGIN}}}", "//{{{HASALLOWEDVALUES_END}}}", WS); } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{HASALLOWEDVALUES_BEGIN}}}", "//{{{HASALLOWEDVALUES_END}}}", WS); } #endregion #region DestroyMicroStack cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); while (en.MoveNext()) { string name = (string)en.Key; UPnPService s = (UPnPService)en.Value; foreach (UPnPStateVariable v in s.GetStateVariables()) { if (v.SendEvent && v.GetNetType() != typeof(bool)) { cs.Append(" free(upnp->" + name + "_" + v.Name + ");" + cl); } } } WS = WS.Replace("//{{{UPnPDestroyMicroStack_FreeEventResources}}}", cs.ToString()); cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); en = SL.GetEnumerator(); while (en.MoveNext()) { string name = (string)en.Key; cs.Append(" sinfo = upnp->HeadSubscriberPtr_" + name + ";" + cl); cs.Append(" while(sinfo!=NULL)" + cl); cs.Append(" {" + cl); cs.Append(" sinfo2 = sinfo->Next;" + cl); cs.Append(" UPnPDestructSubscriberInfo(sinfo);" + cl); cs.Append(" sinfo = sinfo2;" + cl); cs.Append(" }" + cl); } WS = WS.Replace("//{{{UPnPDestroyMicroStack_DestructSubscriber}}}", cs.ToString()); #endregion #region UPnP/1.1 Complex Types cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildComplexTypeParser(SeqTable, ChoTable, cs, SL, this.pc_methodPrefix, this.pc_methodLibPrefix); CPEmbeddedCGenerator.BuildComplexTypeSerializer(SeqTable, ChoTable, cs, SL, this.pc_methodPrefix, this.pc_methodLibPrefix); WS = WS.Replace("//{{{ComplexTypeCode}}}", cs.ToString()); #endregion #region HTTP Version if (!Configuration.HTTP_1dot1) { WS = WS.Replace("!HTTPVERSION!", "1.0"); WS = SourceCodeRepository.RemoveAndClearTag("//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}", "//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}", WS); } else { WS = WS.Replace("!HTTPVERSION!", "1.1"); WS = SourceCodeRepository.RemoveTag("//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}", "//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}", WS); } WS = WS.Replace("!MICROSTACKVERSION!", this.UseVersion); #endregion #region UPnP Specific Version if (device.ArchitectureVersion == "1.0") { // UPnP/1.0 WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_UPnP/1.1_Specific}}}", "//{{{END_UPnP/1.1_Specific}}}", WS); WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_UPnP/1.0_Specific}}}", "//{{{END_UPnP/1.0_Specific}}}", WS); WS = WS.Replace("!UPNPVERSION!", "1.0"); } else { // UPnP/1.1 WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_UPnP/1.0_Specific}}}", "//{{{END_UPnP/1.0_Specific}}}", WS); WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_UPnP/1.1_Specific}}}", "//{{{END_UPnP/1.1_Specific}}}", WS); WS = WS.Replace("!UPNPVERSION!", "1.1"); } #endregion #region Remove Event Processing if no evented State Variables if (DeviceHasEvents(device)) { WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_EVENTPROCESSING}}}", "//{{{END_EVENTPROCESSING}}}", WS); } else { WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_EVENTPROCESSING}}}", "//{{{END_EVENTPROCESSING}}}", WS); } #endregion #region Prefixes WS = FixPrefix_DeviceService(device, WS); WS = WS.Replace("UPnP/", "upnp/"); WS = WS.Replace("UPnPError", "_upnperror_"); WS = WS.Replace(" UPnP ", " _upnp_ "); WS = WS.Replace("UPnP", this.pc_methodPrefix); WS = WS.Replace("ILib", this.pc_methodLibPrefix); WS = WS.Replace("_upnperror_", "UPnPError"); WS = WS.Replace("upnp/", "UPnP/"); WS = WS.Replace(" _upnp_ ", " UPnP "); WS = FixPrefix2_DeviceService(device, WS); #endregion #region Reformat String WS = CodeProcessor.ProcessCode(WS, Indent); #endregion #region Write to disk if (this.Language == LANGUAGES.C) { W = File.CreateText(outputDirectory.FullName + "\\" + pc_methodPrefix + "MicroStack.c"); } else { W = File.CreateText(outputDirectory.FullName + "\\" + pc_methodPrefix + "MicroStack.cpp"); } W.Write(WS); W.Close(); #endregion #endregion #region Sample Application if (BuildSampleApp) { WS = SampleApp; #region Display Message WS = WS.Replace("{{{INITSTRING}}}", (string)FriendlyNameTable[device] + " {{{INITSTRING}}}"); #endregion #region ImplementationMethods if (!Configuration.BareBonesSample) { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildMainUserCode(cs, device, serviceNames); WS = WS.Replace("//{{{DEVICE_INVOCATION_DISPATCH}}}", "//{{{DEVICE_INVOCATION_DISPATCH}}}" + cl + cs.ToString()); } #endregion #region ImplementationMethods: Function Pointer Initialization if (!Configuration.BareBonesSample) { if (Configuration.EXTERN_Callbacks == false) { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.ident = 1; if (DeviceConf.AdvertisesPresentationPage) { cs.Append(pc_methodPrefix + "FP_PresentationPage=&" + pc_methodPrefix + "PresentationRequest;" + cl); } BuildMain_SetFunctionPointers(cs, device, serviceNames); WS = WS.Replace("//{{{INVOCATION_FP}}}", "//{{{INVOCATION_FP}}}" + cl + cs.ToString()); } } #endregion #region PresentationRequest if (DeviceConf.AdvertisesPresentationPage) { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.Append("void UPnPPresentationRequest(void* upnptoken, struct packetheader *packet)" + cl); cs.Append("{" + cl); cs.Append(" printf(\"UPnP Presentation Request: %s %s\\r\\n\", packet->Directive,packet->DirectiveObj);" + cl); cs.Append(cl); cs.Append(" /* TODO: Add Web Response Code Here... */" + cl); cs.Append(" printf(\"HOST: %x\\r\\n\",UPnPGetLocalInterfaceToHost(upnptoken));" + cl); cs.Append(cl); cs.Append(" ILibWebServer_Send_Raw((struct ILibWebServer_Session *)upnptoken, \"HTTP/1.1 200 OK\\r\\nContent-Length: 0\\r\\n\\r\\n\" , 38 , 1, 1);" + cl); cs.Append("}" + cl); WS = WS.Replace("//{{{PresentationRequest}}}", "//{{{PresentationRequest}}}" + cl + cs.ToString()); } #endregion #region MicroStack.h include WS = WS.Replace("//{{{MicroStack_Include}}}", "//{{{MicroStack_Include}}}" + cl + "#include \"UPnPMicroStack.h\""); #endregion #region MicroStack Veriable Declaration WS = WS.Replace("//{{{MICROSTACK_VARIABLE}}}", "//{{{MICROSTACK_VARIABLE}}}" + cl + "void *UPnPmicroStack;"); #endregion #region CreateMicroStack if (!Configuration.BareBonesSample) { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); cs.ident = 1; cs.Append(" // TODO: Each device must have a unique device identifier (UDN)" + cl); cs.Append(" " + this.pc_methodPrefix + "microStack = " + pc_methodPrefix + "CreateMicroStack(MicroStackChain, "); CreateMicroStack_Device_Values(cs, device); cs.Append("\"" + Guid.NewGuid().ToString() + "\", \"0000001\", " + DeviceConf.SSDPCycleTime.ToString() + ", " + DeviceConf.WebPort.ToString() + ");" + cl); WS = WS.Replace("//{{{CREATE_MICROSTACK}}}", "//{{{CREATE_MICROSTACK}}}" + cl + cs.ToString()); } #endregion #region InitialEvent Initialization if (!Configuration.BareBonesSample) { cs = new CodeProcessor(new StringBuilder(), this.Language == LANGUAGES.CPP); BuildStateVariableEventingSample(cs, device, serviceNames); WS = WS.Replace("//{{{STATEVARIABLES_INITIAL_STATE}}}", "//{{{STATEVARIABLES_INITIAL_STATE}}}" + cl + cs.ToString()); } #endregion #region IPAddress Monitor if (Configuration.DefaultIPAddressMonitor) { WS = WS.Replace("//{{{IPAddress_Changed}}}", "//{{{IPAddress_Changed}}}" + cl + "UPnPIPAddressListChanged(UPnPmicroStack);"); if (Configuration.TargetPlatform == ServiceGenerator.PLATFORMS.MICROSTACK_WINSOCK2) { WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_WINSOCK2_IPADDRESS_MONITOR}}}", "//{{{END_WINSOCK2_IPADDRESS_MONITOR}}}", WS); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_POSIX/WINSOCK1_IPADDRESS_MONITOR}}}", "//{{{END_POSIX/WINSOCK1_IPADDRESS_MONITOR}}}", WS); } else { WS = SourceCodeRepository.RemoveTag("//{{{BEGIN_POSIX/WINSOCK1_IPADDRESS_MONITOR}}}", "//{{{END_POSIX/WINSOCK1_IPADDRESS_MONITOR}}}", WS); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_WINSOCK2_IPADDRESS_MONITOR}}}", "//{{{END_WINSOCK2_IPADDRESS_MONITOR}}}", WS); } } else { WS = WS.Replace("//{{{IPAddress_Changed}}}", ""); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_WINSOCK2_IPADDRESS_MONITOR}}}", "//{{{END_WINSOCK2_IPADDRESS_MONITOR}}}", WS); WS = SourceCodeRepository.RemoveAndClearTag("//{{{BEGIN_POSIX/WINSOCK1_IPADDRESS_MONITOR}}}", "//{{{END_POSIX/WINSOCK1_IPADDRESS_MONITOR}}}", WS); } #endregion #region Prefixes WS = WS.Replace("UPnPAbstraction.h", "_upnpabstraction.h_"); WS = WS.Replace("pUPnP", "_pupnp_"); WS = WS.Replace("CUPnP_", "_cupnp_"); WS = WS.Replace("UPnP/", "upnp/"); WS = WS.Replace("UPnPControlPointStructs.h", "upnpcontrolpointstructs.h"); WS = WS.Replace("UPnPDevice", "upnpdevice"); WS = WS.Replace("UPnPService", "upnpservice"); WS = WS.Replace("SubscribeForUPnPEvents", "subscribeforupnpevents"); WS = WS.Replace("UnSubscribeUPnPEvents", "unsubscribeupnpevents"); WS = WS.Replace("UPnPError", "_upnperror_"); WS = WS.Replace(" UPnP ", " _upnp_ "); WS = WS.Replace("UPnP", this.pc_methodPrefix); WS = WS.Replace("ILib", this.pc_methodLibPrefix); WS = WS.Replace("_upnperror_", "UPnPError"); WS = WS.Replace("upnp/", "UPnP/"); WS = WS.Replace(" _upnp_ ", " UPnP "); WS = WS.Replace("_pupnp_", "pUPnP"); WS = WS.Replace("_cupnp_", "CUPnP_"); WS = WS.Replace("upnpdevice", "UPnPDevice"); WS = WS.Replace("upnpservice", "UPnPService"); WS = WS.Replace("upnpcontrolpointstructs.h", "UPnPControlPointStructs.h"); WS = WS.Replace("subscribeforupnpevents", "SubscribeForUPnPEvents"); WS = WS.Replace("unsubscribeupnpevents", "UnSubscribeUPnPEvents"); WS = WS.Replace("_upnpabstraction.h_", "UPnPAbstraction.h"); #endregion SampleApp = WS; } #endregion Log("UPnP Stack Generation Complete."); return true; }
public override void Start(UPnPDevice device) { if(!Enabled) return; UPnPDevice dv = device; while(dv.ParentDevice!=null) { dv = dv.ParentDevice; } state = UPnPTestStates.Running; UPnPService[] _S = device.GetServices("urn:"); foreach(UPnPService s in _S) { bool ok = false; foreach(UPnPStateVariable v in s.GetStateVariables()) { if(v.SendEvent) { ok = true; break; } } if(ok) { UPnPDebugObject d = new UPnPDebugObject(s); Uri EventUri = new Uri((string)d.GetField("__eventurl")); IPEndPoint dest = new IPEndPoint(IPAddress.Parse(EventUri.Host),EventUri.Port); HTTPMessage R = new HTTPMessage(); R.Directive = "SUBSCRIBE"; R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery); R.AddTag("Host",dest.ToString()); R.AddTag("Callback","<http://" + dv.InterfaceToHost.ToString()+ ":" + NetworkInfo.GetFreePort(10000,50000,dv.InterfaceToHost).ToString() + ">"); //R.AddTag("Callback","<http://127.0.0.1:55555>"); R.AddTag("NT","upnp:event"); R.AddTag("Timeout","Second-15"); System.Console.WriteLine(R.GetTag("Callback")); MRE.Reset(); SID = ""; StartCountDown(30); HTTPRequest rq = new HTTPRequest(); rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink); AddHTTPMessage(R); rq.PipelineRequest(dest,R,s); MRE.WaitOne(30000,false); AbortCountDown(); if (SID=="") { AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE: " + s.ServiceURN + " << FAILED >>"); AddEvent(LogImportance.Remark,"Subscribe","Aborting tests"); result = "Subscription test failed."; // TODO state = UPnPTestStates.Failed; return; } else { AddEvent(LogImportance.Remark,"Subscribe","SUBSCRIBE: " + s.ServiceURN + " << OK >>"); // Renew Test R = new HTTPMessage(); R.Directive = "SUBSCRIBE"; R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery); R.AddTag("Host",dest.ToString()); R.AddTag("SID",SID); R.AddTag("Timeout","Second-15"); StartCountDown(30); SID = ""; MRE.Reset(); AddHTTPMessage(R); rq = new HTTPRequest(); rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink); rq.PipelineRequest(dest,R,s); MRE.WaitOne(30000,false); AbortCountDown(); if (SID=="") { AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE (Renew): " + s.ServiceURN + " << FAILED >>"); AddEvent(LogImportance.Remark,"Subscribe","Aborting tests"); result = "Subscription test failed."; // TODO state = UPnPTestStates.Failed; return; } else { AddEvent(LogImportance.Remark,"Subscribe","SUBSCRIBE (Renew): " + s.ServiceURN + " << OK >>"); // Cancel R = new HTTPMessage(); R.Directive = "UNSUBSCRIBE"; R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery); R.AddTag("Host",dest.ToString()); R.AddTag("SID",SID); StartCountDown(30); SID = ""; MRE.Reset(); rq = new HTTPRequest(); rq.OnResponse += new HTTPRequest.RequestHandler(CancelSink); AddHTTPMessage(R); rq.PipelineRequest(dest,R,s); MRE.WaitOne(30000,false); AbortCountDown(); if (SID=="") { AddEvent(LogImportance.Critical,"Subscribe","UNSUBSCRIBE: " + s.ServiceURN + " << FAILED >>"); AddEvent(LogImportance.Remark,"Subscribe","Aborting tests"); result = "Subscription test failed."; state = UPnPTestStates.Failed; return; } else { AddEvent(LogImportance.Remark,"Subscribe","UNSUBSCRIBE: " + s.ServiceURN + " << OK >>"); } /* Test for duplicate SID * as well as initial events */ EventTable.Clear(); NumEvents = 0; foreach(UPnPStateVariable V in s.GetStateVariables()) { if(V.SendEvent) { ++ NumEvents; EventTable[V.Name] = false; V.OnModified -= new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink); V.OnModified += new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink); } } if(EventTable.Count>0) { MRE.Reset(); s.OnSubscribe -= new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink); s.OnSubscribe += new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink); s.UnSubscribe(null); foreach(UPnPStateVariable V in s.GetStateVariables()) { V.Clear(); } s.Subscribe(120,null); MRE.WaitOne(30000,false); if(SID=="") { // Subscribe Failed AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED >>"); AddEvent(LogImportance.Remark,"Subscribe","Aborting tests"); result = "Subscription test failed."; state = UPnPTestStates.Failed; return; } else { if(SID==null) { // Duplicate SID // Subscribe Failed AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, duplicate SID >>"); AddEvent(LogImportance.Remark,"Subscribe","Aborting tests"); result = "Subscription test failed."; state = UPnPTestStates.Failed; return; } else { // Check Hashtable IDictionaryEnumerator de = EventTable.GetEnumerator(); bool OK = true; while(de.MoveNext()) { if((bool)de.Value==false) { // No Event Received OK = false; AddEvent(LogImportance.Critical,"Subscribe"," StateVariable: " + (string)de.Key + " >> Event NOT received"); } else { // OK AddEvent(LogImportance.Remark,"Subscribe"," StateVariable: " + (string)de.Key + " >> Event OK"); } } if(OK==false) { AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, Did not receive all events >>"); AddEvent(LogImportance.Remark,"Subscribe","Aborting tests"); result = "Subscription test failed."; state = UPnPTestStates.Failed; return; } } } } } } } } result = "Subscribe Tests OK"; state = UPnPTestStates.Pass; }