Da mir das ein- und ausschalten über das Web-Interface lästig ist, habe ich mir jetzt die Funktionen für HTTP und JSON angeschaut um das ganze zu automatisieren.
Anbei der Code um das WLAN ein- oder auszuschalten, je nach aktuellen Status. Dem Programm muss das Kennwort für die Anmeldung übergeben werden. Eventuell muss noch der Wert für den Header "_TclRequestVerificationKey" für das aktuelle Gerät ermittelt werden.
Peter
Code: Alles auswählen
; Schaltet das 2,4 GHz WLAN am Alcatel Router HH71 aus oder ein, je nach aktuellen Zustand.
; Es wird die unverschlüsselte HTTP-Verbindung verwendet.
EnableExplicit
; Die Debugausgaben funktionieren damit in der kompilierten Exe-Datei für 'DebugView'.
; Macro Debug(sText)
; OutputDebugString_(sText)
; EndMacro
Global gfWlanStatus.i, gsJsonResponseError.s, gsJsonGetWlanSettingsResponse.s
Global NewMap gHeaderMap.s()
#sProgramTitle = "WLAN-Ein- oder Ausschalten"
#sIP = "192.168.1.1"
#sUrl = "http://" + #sIP
#sUrlWebApi = #sUrl + "/jrd/webapi"
#sUserName = "admin"
; Der Header "_TclRequestVerificationKey" muss immer mit gesendet werden. Der Wert stammt aus den empfangenen Daten.
; Wahrscheinlich unterscheidet sich der Wert zwischen den Geräten.
#sTclRequestVerificationKey = "KSDHSDFOGQ5WERYTUIQWERTYUISDFG1HJZXCVCXBN2GDSMNDHKVKFsVBNf"
Procedure.s EncryptAdmin(sValue.s)
Protected sReturn.s, sKey.s, iLen.i, c.i, iValueCode.i, iKeyCode.i, sEncrypted.s
; https://github.com/spolette/Alcatel_HH72
sKey = "e5dl12XYVggihggafXWf0f2YSf2Xngd1"
iLen = Len(sValue) - 1
For c = 0 To iLen
iValueCode = Asc(Mid(sValue, c + 1, 1))
iKeyCode = Asc(Mid(sKey, Mod(c, Len(sKey)) + 1, 1))
sEncrypted + Chr(($F0 & iKeyCode) | (($0F & iValueCode) ! ($0F & iKeyCode)))
sEncrypted + Chr(($F0 & iKeyCode) | ((iValueCode >> 4) ! ($0F & iKeyCode)))
Next
ProcedureReturn sEncrypted
EndProcedure
Procedure.i GetJsonValue(iJsonValueNumber.i, sObjectName.s, sValueName.s, *usValue.String, *uiType.Integer)
Protected fResult.i, iReturn.i, sMemberName.s, iObjectNumber.i
*usValue\s = #Null$
*uiType\i = #PB_Default
fResult = Bool(iJsonValueNumber)
If Not fResult
Debug("GetJsonValue Fehler: iJsonValueNumber ist Null.")
EndIf
If fResult
fResult = Bool(ExamineJSONMembers(iJsonValueNumber))
If Not fResult
Debug("GetJsonValue Fehler: Das JSON-Objekt kann nicht untersucht werden.")
EndIf
EndIf
If fResult
While NextJSONMember(iJsonValueNumber)
sMemberName = JSONMemberKey(iJsonValueNumber)
;Debug("sMemberName: " + sMemberName)
If Len(sObjectName)
If (sMemberName = sObjectName)
iObjectNumber = JSONMemberValue(iJsonValueNumber)
;Debug("Rekursiv")
iReturn = GetJsonValue(iObjectNumber, #Null$, sValueName, *usValue, *uiType)
Break
EndIf
ElseIf (sMemberName = sValueName)
iObjectNumber = JSONMemberValue(iJsonValueNumber)
*uiType\i = JSONType(iObjectNumber)
Select *uiType\i
Case #PB_JSON_Null
*usValue\s = #Null$
Case #PB_JSON_String
*usValue\s = GetJSONString(iObjectNumber)
Case #PB_JSON_Number
*usValue\s = Str(GetJSONInteger(iObjectNumber))
Case #PB_JSON_Boolean
*usValue\s = Str(GetJSONBoolean(iObjectNumber))
Case #PB_JSON_Array
*usValue\s = "ArraySize: " + JSONArraySize(iObjectNumber)
Case #PB_JSON_Object
*usValue\s = "ObjectSize: " + JSONObjectSize(iObjectNumber)
EndSelect
iReturn = iObjectNumber
Break
EndIf
Wend
EndIf
ProcedureReturn iReturn
EndProcedure
Procedure.s GetJsonResponseError(iJsonNumber.i)
Protected sReturn.s, fResult.i, iJsonObjectNumber.i, usValue.String, uiType.Integer, sCode.s, sMessage.s
; Den Fehler ermitteln und zurückgeben.
; { "jsonrpc": "2.0", "error": { "code": "010101", "message": "Username or Password is not correct." }, "id": "12" }
If iJsonNumber
iJsonObjectNumber = GetJsonValue(JSONValue(iJsonNumber), "error", "code", usValue, uiType)
If (iJsonObjectNumber And Len(usValue\s))
sCode = usValue\s
EndIf
iJsonObjectNumber = GetJsonValue(JSONValue(iJsonNumber), "error", "message", usValue, uiType)
If (iJsonObjectNumber And Len(usValue\s))
sMessage = usValue\s
EndIf
sReturn = sMessage + " (" + sCode + ")"
EndIf
ProcedureReturn sReturn
EndProcedure
Procedure.s CreateJsonMethod(sMethod.s, sPassword.s = #Null$)
Protected sReturn.s, iJsonNumber.i, iObjectNumber.i
; Die JSON-RPC-Daten erstellen, z.B.:
; {"id":"12","jsonrpc":"2.0","method":"Login","params":{"UserName":"xxxxx","Password":"xxxxx"}}
; {"id":"12","jsonrpc":"2.0","method":"GetWlanSettings","params":{}}
iJsonNumber = CreateJSON(#PB_Any)
iObjectNumber = SetJSONObject(JSONValue(iJsonNumber))
SetJSONString(AddJSONMember(iObjectNumber, "id"), "12")
SetJSONString(AddJSONMember(iObjectNumber, "jsonrpc"), "2.0")
SetJSONString(AddJSONMember(iObjectNumber, "method"), sMethod)
iObjectNumber = AddJSONMember(iObjectNumber, "params")
SetJSONObject(iObjectNumber)
If (sMethod = "Login")
SetJSONString(AddJSONMember(iObjectNumber, "UserName"), EncryptAdmin(#sUserName))
SetJSONString(AddJSONMember(iObjectNumber, "Password"), EncryptAdmin(sPassword))
EndIf
sReturn = ComposeJSON(iJsonNumber)
FreeJSON(iJsonNumber)
ProcedureReturn sReturn
EndProcedure
;-
Procedure.i Login(sPassword.s)
Protected fReturn.i, fResult.i, iJsonNumber.i, iObjectNumber.i, sJsonRpc.s
Protected iRequestIdentifier.i, sResponse.s
Protected usValue.String, uiType.Integer
; Die JSON-RPC-Daten erstellen.
; {"id":"12","jsonrpc":"2.0","method":"Login","params":{"UserName":"xxxxx","Password":"xxxxx"}}
sJsonRpc = CreateJsonMethod("Login", sPassword)
; Die Daten für das Anmelden senden.
gHeaderMap("Content-Length") = Str(StringByteLength(sJsonRpc, #PB_UTF8))
iRequestIdentifier.i = HTTPRequest(#PB_HTTP_Post, #sUrlWebApi, sJsonRpc, #PB_HTTP_Debug, gHeaderMap())
; Die Antwort einlesen und das Token ermitteln.
; { "jsonrpc": "2.0", "result": { "token": 74097316 }, "id": "12" }
If iRequestIdentifier
Debug("Login Response:")
sResponse = HTTPInfo(iRequestIdentifier, #PB_HTTP_Response, #PB_UTF8)
Debug(sResponse)
FinishHTTP(iRequestIdentifier)
iJsonNumber = ParseJSON(#PB_Any, sResponse)
If iJsonNumber
iObjectNumber = GetJsonValue(JSONValue(iJsonNumber), "result", "token", usValue, uiType)
fReturn = Bool(iObjectNumber And Len(usValue\s))
; Das Token zu den Header-Daten hinzufügen.
If fReturn
Debug("Login Token: " + usValue\s)
gHeaderMap("_TclRequestVerificationToken") = EncryptAdmin(usValue\s)
Else
gsJsonResponseError = GetJsonResponseError(iJsonNumber)
EndIf
FreeJSON(iJsonNumber)
EndIf
EndIf
ProcedureReturn fReturn
EndProcedure
Procedure.i GetWlanSettings()
Protected fReturn.i, iJsonNumber.i, iObjectNumber.i, sJsonRpc.s
Protected iRequestIdentifier.i, sResponse.s
Protected usValue.String, uiType.Integer
; Die JSON-RPC-Daten erstellen.
; {"id":"12","jsonrpc":"2.0","method":"GetWlanSettings","params":{}}
sJsonRpc = CreateJsonMethod("GetWlanSettings")
; Die Daten für die WLAN-Einstellungen senden.
gHeaderMap("Content-Length") = Str(StringByteLength(sJsonRpc, #PB_UTF8))
iRequestIdentifier.i = HTTPRequest(#PB_HTTP_Post, #sUrlWebApi, sJsonRpc, #PB_HTTP_Debug, gHeaderMap())
; Die Antwort einlesen und den Status des WLANs ermitteln.
; { "jsonrpc": "2.0", "result": { "WiFiOffTime": 0, "AP2G": { "CountryCode": "AT", "ApStatus": 0, "WMode": 3, "Ssid": "WLAN123",
; "SsidHidden": 0, "Channel": 0, "SecurityMode": 3, "WepType": 0, "WpaType": 1, "WepKey": "xxxxx", "WpaKey": "xxxxx",
; "ApIsolation": 0, "max_numsta": 5, "curr_num": 0, "CurChannel": 0, "Bandwidth": 0 }, "AP5G": { "CountryCode": "AT", "ApStatus": 0,
; "WMode": 6, "Ssid": "HH71VM_33C7_5G", "SsidHidden": 0, "Channel": 0, "SecurityMode": 3, "WepType": 0, "WpaType": 1,
; "WepKey": "xxxxx", "WpaKey": "xxxxx", "ApIsolation": 0, "max_numsta": 32, "curr_num": 0, "CurChannel": 0,
; "Bandwidth": 4 } }, "id": "12" }
If iRequestIdentifier
Debug("GetWlanSettings Response:")
sResponse = HTTPInfo(iRequestIdentifier, #PB_HTTP_Response, #PB_UTF8)
Debug(sResponse)
FinishHTTP(iRequestIdentifier)
iJsonNumber = ParseJSON(#PB_Any, sResponse)
If iJsonNumber
iObjectNumber = GetJsonValue(JSONValue(iJsonNumber), "result", "AP2G", usValue, uiType)
iObjectNumber = GetJsonValue(iObjectNumber, #Null$, "ApStatus", usValue, uiType)
fReturn = Bool(iObjectNumber And Len(usValue\s))
If fReturn
gfWlanStatus = Val(usValue\s)
Debug("GetWlanSettings WLAN-Status: " + gfWlanStatus)
Else
gsJsonResponseError = GetJsonResponseError(iJsonNumber)
EndIf
FreeJSON(iJsonNumber)
; Response sichern für SetWlanSettings().
gsJsonGetWlanSettingsResponse = sResponse
EndIf
EndIf
ProcedureReturn fReturn
EndProcedure
Procedure.i SetWlanSettings()
Protected fReturn.i, fResult.i, iJsonNumber.i, iObjectNumber.i, sJsonRpc.s
Protected iRequestIdentifier.i, sResponse.s
Protected usValue.String, uiType.Integer
; Die empfangenen WLAN-Daten:
; { "jsonrpc": "2.0", "result": { "WiFiOffTime": 0, "AP2G": { "CountryCode": "AT", "ApStatus": 0, "WMode": 3, "Ssid": "WLAN123",
; "SsidHidden": 0, "Channel": 0, "SecurityMode": 3, "WepType": 0, "WpaType": 1, "WepKey": "xxxxx", "WpaKey": "xxxxx",
; "ApIsolation": 0, "max_numsta": 5, "curr_num": 0, "CurChannel": 0, "Bandwidth": 0 }, "AP5G": { "CountryCode": "AT", "ApStatus": 0,
; "WMode": 6, "Ssid": "HH71VM_33C7_5G", "SsidHidden": 0, "Channel": 0, "SecurityMode": 3, "WepType": 0, "WpaType": 1,
; "WepKey": "xxxxx", "WpaKey": "xxxxx", "ApIsolation": 0, "max_numsta": 32, "curr_num": 0, "CurChannel": 0,
; "Bandwidth": 4 } }, "id": "12" }
; Die gesendeten WLAN-Daten über das Web-Interface:
; {"id":"12","jsonrpc":"2.0","method":"SetWlanSettings","params":{"show2GPassword":false,"show5GPassword":false,
; "showAP2G_guestPassword":false,"WiFiOffTime":0,"AP2G":{"CountryCode":"AT","ApStatus":1,"WMode":3,"Ssid":"WLAN123",
; "SsidHidden":0,"Channel":0,"SecurityMode":3,"WepType":0,"WpaType":1,"WepKey":"xxxxx","WpaKey":"xxxxx",
; "ApIsolation":0,"max_numsta":5,"curr_num":0,"CurChannel":0,"Bandwidth":0},"AP2G_guest":{"ApStatus":0,"WMode":3,
; "CountryCode":"CN","Ssid":"","SsidHidden":0,"Channel":0,"SecurityMode":3,"WepType":0,"WepKey":"xxxxx","WpaType":1,
; "WpaKey":"xxxxx","ApIsolation":0,"max_numsta":15,"curr_num":0,"CurChannel":8,"Bandwidth":0},"AP5G":{"CountryCode":"AT",
; "ApStatus":0,"WMode":6,"Ssid":"HH71VM_33C7_5G","SsidHidden":0,"Channel":0,"SecurityMode":3,"WepType":0,"WpaType":1,
; "WepKey":"xxxxx","WpaKey":"xxxxx","ApIsolation":0,"max_numsta":32,"curr_num":0,"CurChannel":0,"Bandwidth":4}}}
; Es genügt die empfangenen WLAN-Einstellungen zu senden, mit dem geänderten WLAN-Status.
fResult = Bool(Len(gsJsonGetWlanSettingsResponse))
If Not fResult
Debug("SetWlanSettings Fehler: Die WLAN-Einstellungen sind nicht vorhanden.")
EndIf
If fResult
iJsonNumber = ParseJSON(#PB_Any, gsJsonGetWlanSettingsResponse)
fResult = Bool(iJsonNumber)
If Not fResult
Debug("SetWlanSettings Fehler: Das JSON-Objekt konnte nicht mit den eingelesenen WLAN-Daten erstellt werden.")
EndIf
EndIf
If fResult
; Werte zu den empfangenen WLAN-Daten hinzufügen.
iObjectNumber = JSONValue(iJsonNumber)
SetJSONString(AddJSONMember(iObjectNumber, "method"), "SetWlanSettings")
EndIf
If fResult
; Den WLAN-Status ändern.
iObjectNumber = GetJsonValue(iObjectNumber, "result", "AP2G", usValue, uiType)
fResult = Bool(iObjectNumber)
If Not fResult
Debug("SetWlanSettings Fehler: Objekt AP2G ist nicht vorhanden.")
Else
iObjectNumber = GetJsonValue(iObjectNumber, #Null$, "ApStatus", usValue, uiType)
fResult = Bool(iObjectNumber And Len(usValue\s))
If Not fResult
Debug("SetWlanSettings Fehler: Member ApStatus ist in Objekt AP2G nicht vorhanden.")
Else
SetJSONInteger(iObjectNumber, Bool(Not gfWlanStatus))
Debug("SetWlanSettings ApStatus: " + GetJSONInteger(iObjectNumber))
EndIf
EndIf
EndIf
If fResult
; Den Namen des Objekts "result" in "params" ändern.
; Das Ändern ist anscheinend nicht mit JSON-Funktionen möglich.
sJsonRpc = ComposeJSON(iJsonNumber)
fResult = Bool(FindString(sJsonRpc, ~"\"result\""))
If Not fResult
Debug("SetWlanSettings Fehler: Das Objekt 'result' ist nicht vorhanden.")
Else
ReplaceString(sJsonRpc, ~"\"result\"", ~"\"params\"", #PB_String_InPlace, 1, 1)
Debug("SetWlanSettings Neue JSON-Daten:")
Debug(sJsonRpc)
EndIf
EndIf
If iJsonNumber
FreeJSON(iJsonNumber)
EndIf
If fResult
; Die geänderten Daten für die WLAN-Einstellungen senden.
gHeaderMap("Content-Length") = Str(StringByteLength(sJsonRpc, #PB_UTF8))
iRequestIdentifier.i = HTTPRequest(#PB_HTTP_Post, #sUrlWebApi, sJsonRpc, #PB_HTTP_Debug, gHeaderMap())
; Die Antwort einlesen und den Erfolg ermitteln.
; { "jsonrpc": "2.0", "result": { }, "id": "12" }
If iRequestIdentifier
Debug("SetWlanSettings Response:")
sResponse = HTTPInfo(iRequestIdentifier, #PB_HTTP_Response, #PB_UTF8)
Debug(sResponse)
FinishHTTP(iRequestIdentifier)
iJsonNumber = ParseJSON(#PB_Any, sResponse)
If iJsonNumber
iObjectNumber = GetJsonValue(JSONValue(iJsonNumber), #Null$, "result", usValue, uiType)
fReturn = Bool(iObjectNumber And Len(usValue\s))
If fReturn
Debug("SetWlanSettings Erfolgreich")
Else
gsJsonResponseError = GetJsonResponseError(iJsonNumber)
EndIf
FreeJSON(iJsonNumber)
EndIf
EndIf
EndIf
ProcedureReturn fReturn
EndProcedure
Procedure.i Logout()
Protected fReturn.i, iJsonNumber.i, iObjectNumber.i, sJsonRpc.s
Protected iRequestIdentifier.i, sResponse.s
Protected usValue.String, uiType.Integer
; Die JSON-RPC-Daten erstellen.
; {"id":"12","jsonrpc":"2.0","method":"Logout","params":{}}
sJsonRpc = CreateJsonMethod("Logout")
; Die Daten für das Abmelden senden.
gHeaderMap("Content-Length") = Str(StringByteLength(sJsonRpc, #PB_UTF8))
iRequestIdentifier.i = HTTPRequest(#PB_HTTP_Post, #sUrlWebApi, sJsonRpc, #PB_HTTP_Debug, gHeaderMap())
; Die Antwort einlesen und den Erfolg ermitteln.
; { "jsonrpc": "2.0", "result": { }, "id": "12" }
If iRequestIdentifier
Debug("Logout Response:")
sResponse = HTTPInfo(iRequestIdentifier, #PB_HTTP_Response, #PB_UTF8)
Debug(sResponse)
FinishHTTP(iRequestIdentifier)
iJsonNumber = ParseJSON(#PB_Any, sResponse)
If iJsonNumber
iObjectNumber = GetJsonValue(JSONValue(iJsonNumber), #Null$, "result", usValue, uiType)
fReturn = Bool(iObjectNumber And Len(usValue\s))
If fReturn
Debug("Logout Erfolgreich")
Else
gsJsonResponseError = GetJsonResponseError(iJsonNumber)
EndIf
FreeJSON(iJsonNumber)
EndIf
EndIf
ProcedureReturn fReturn
EndProcedure
;-
Procedure Main()
Protected sPassword.s, fResult.i, fLogin.i
; Das Kennwort ermitteln.
fResult = Bool(CountProgramParameters())
If Not fResult
MessageRequester(#sProgramTitle, "Es wurde kein Kennwort für die Anmeldung übergeben.", #PB_MessageRequester_Error)
Else
sPassword = ProgramParameter(0)
EndIf
; Header für den HTTPRequest erstellen.
If fResult
gHeaderMap("Referer") = #sUrl + "/"
gHeaderMap("_TclRequestVerificationKey") = #sTclRequestVerificationKey
gHeaderMap("Content-Type") = "application/json;charset=utf-8"
gHeaderMap("X-Requested-With") = "XMLHttpRequest"
gHeaderMap("Origin") = #sUrl
EndIf
; Anmelden.
If fResult
fResult = Login(sPassword)
fLogin = fResult
If Not fResult
MessageRequester(#sProgramTitle, "Fehler bei Anmelden." + #CRLF$ + gsJsonResponseError, #PB_MessageRequester_Error)
EndIf
EndIf
; Die Wlan-Einstellungen einlesen und den Status des WLAN ermitteln.
If fResult
fResult = GetWlanSettings()
If Not fResult
MessageRequester(#sProgramTitle, "Fehler bei WLAN-Einstellungen einlesen." + #CRLF$ + gsJsonResponseError,
#PB_MessageRequester_Error)
EndIf
EndIf
; Die WLAN-Einstellung für AP2G ändern und die Einstellungen senden.
If fResult
fResult = SetWlanSettings()
If Not fResult
MessageRequester(#sProgramTitle, "Fehler bei WLAN-Einstellungen ändern." + #CRLF$ + gsJsonResponseError,
#PB_MessageRequester_Error)
EndIf
EndIf
; Abmelden.
If fLogin
fResult = Logout()
If Not fResult
MessageRequester(#sProgramTitle, "Fehler bei Abmelden." + #CRLF$ + gsJsonResponseError, #PB_MessageRequester_Error)
EndIf
EndIf
EndProcedure
;- Start
Main()