diff --git a/NOnStar.ConsoleApp/NOnStar.ConsoleApp.csproj b/NOnStar.ConsoleApp/NOnStar.ConsoleApp.csproj new file mode 100644 index 0000000..1622ce3 --- /dev/null +++ b/NOnStar.ConsoleApp/NOnStar.ConsoleApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + diff --git a/NOnStar.ConsoleApp/Program.cs b/NOnStar.ConsoleApp/Program.cs new file mode 100644 index 0000000..0bae94a --- /dev/null +++ b/NOnStar.ConsoleApp/Program.cs @@ -0,0 +1,22 @@ +using System; + +namespace NOnStar.ConsoleApp +{ + class Program + { + static void Main(string[] args) + { + //must specify email address, password & PIN used for OnStar + var client = new OnStarClient("your_email_address", "onstar_password", "pin"); + + //Uncomment and try one: + //client.UnlockVehical().GetAwaiter().GetResult(); + //client.LockVehical().GetAwaiter().GetResult(); + //client.StartVehical().GetAwaiter().GetResult(); + //client.StopVehical().GetAwaiter().GetResult(); + + Console.WriteLine("Done"); + Console.ReadLine(); + } + } +} diff --git a/NOnStar.sln b/NOnStar.sln new file mode 100644 index 0000000..a9198aa --- /dev/null +++ b/NOnStar.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2035 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NOnStar", "NOnStar\NOnStar.csproj", "{B2E505EC-2F16-4DF1-9AA9-80176658D455}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NOnStar.ConsoleApp", "NOnStar.ConsoleApp\NOnStar.ConsoleApp.csproj", "{F9E9AE6A-1D1F-4D25-8ECF-41A16E17707D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2E505EC-2F16-4DF1-9AA9-80176658D455}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2E505EC-2F16-4DF1-9AA9-80176658D455}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2E505EC-2F16-4DF1-9AA9-80176658D455}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2E505EC-2F16-4DF1-9AA9-80176658D455}.Release|Any CPU.Build.0 = Release|Any CPU + {F9E9AE6A-1D1F-4D25-8ECF-41A16E17707D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9E9AE6A-1D1F-4D25-8ECF-41A16E17707D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9E9AE6A-1D1F-4D25-8ECF-41A16E17707D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9E9AE6A-1D1F-4D25-8ECF-41A16E17707D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A727B3BB-C9A5-4273-A4B8-705522DE1F87} + EndGlobalSection +EndGlobal diff --git a/NOnStar/Auth.cs b/NOnStar/Auth.cs new file mode 100644 index 0000000..a1f5756 --- /dev/null +++ b/NOnStar/Auth.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar +{ + abstract class BaseAuth + { + public string nonce = GetNonce(); + public string timestamp = GetTimestamp(); + + protected static string GetNonce() + { + return Guid.NewGuid().ToString("N").ToLower(); + } + + protected static string GetTimestamp() + { + return DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); + } + } + + class DeviceAuth : BaseAuth + { + public string client_id; + public string device_id; + public string grant_type; + public string username; + public string password; + public string scope = "onstar gmoc commerce msso"; + } + + + class PinAuth : BaseAuth + { + public string credential; + public string device_id; + public string scope = "onstar commerce"; + public string credential_type = "PIN"; + public string client_id; + } +} diff --git a/NOnStar/CommandAndControl/Body.cs b/NOnStar/CommandAndControl/Body.cs new file mode 100644 index 0000000..b16c166 --- /dev/null +++ b/NOnStar/CommandAndControl/Body.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.CommandAndControl +{ + class Body + { + public Error error { get; set; } + } +} diff --git a/NOnStar/CommandAndControl/CommandRequestStatus.cs b/NOnStar/CommandAndControl/CommandRequestStatus.cs new file mode 100644 index 0000000..7d0c422 --- /dev/null +++ b/NOnStar/CommandAndControl/CommandRequestStatus.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.CommandAndControl +{ + public class CommandRequestStatus + { + public bool Successful { get; internal set; } + public string ErrorMessage { get; internal set; } + + public static CommandRequestStatus GetSuccessful() + { + return new CommandRequestStatus() { Successful = true }; + } + + public static CommandRequestStatus GetFailed(string errorMessage) + { + return new CommandRequestStatus() { Successful = false, ErrorMessage = errorMessage }; + } + } + + public class CommandRequestStatus : CommandRequestStatus + { + public T Content { get; internal set; } + + public static CommandRequestStatus GetSuccessful(T content) + { + return new CommandRequestStatus() { Successful = true, Content = content }; + } + + public static new CommandRequestStatus GetFailed(string errorMessage) + { + return new CommandRequestStatus() { Successful = false, ErrorMessage = errorMessage }; + } + } +} diff --git a/NOnStar/CommandAndControl/CommandResponse.cs b/NOnStar/CommandAndControl/CommandResponse.cs new file mode 100644 index 0000000..9dbd7e9 --- /dev/null +++ b/NOnStar/CommandAndControl/CommandResponse.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.CommandAndControl +{ + class CommandResponse + { + public DateTime requestTime { get; set; } + public DateTime completionTime { get; set; } + public string url { get; set; } + public string status { get; set; } + public string type { get; set; } + public Body body { get; set; } + } +} diff --git a/NOnStar/CommandAndControl/Error.cs b/NOnStar/CommandAndControl/Error.cs new file mode 100644 index 0000000..2f22a56 --- /dev/null +++ b/NOnStar/CommandAndControl/Error.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.CommandAndControl +{ + class Error + { + public string code { get; set; } + public string description { get; set; } + public string subCode { get; set; } + public string subCodeDescription { get; set; } + } +} diff --git a/NOnStar/CommandAndControl/OuterCommandResponse.cs b/NOnStar/CommandAndControl/OuterCommandResponse.cs new file mode 100644 index 0000000..3d931a2 --- /dev/null +++ b/NOnStar/CommandAndControl/OuterCommandResponse.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.CommandAndControl +{ + class OuterCommandResponse + { + public CommandResponse commandResponse { get; set; } + } +} diff --git a/NOnStar/ExtensionMethods.cs b/NOnStar/ExtensionMethods.cs new file mode 100644 index 0000000..79f37e0 --- /dev/null +++ b/NOnStar/ExtensionMethods.cs @@ -0,0 +1,35 @@ +using JWT.Builder; +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar +{ + static class ExtensionMethods + { + public static JwtBuilder AddClaims(this JwtBuilder builder, DeviceAuth deviceAuth) + { + return builder + .AddClaim("client_id", deviceAuth.client_id) + .AddClaim("device_id", deviceAuth.device_id) + .AddClaim("username", deviceAuth.username) + .AddClaim("password", deviceAuth.password) + .AddClaim("nonce", deviceAuth.nonce) + .AddClaim("timestamp", deviceAuth.timestamp) + .AddClaim("scope", deviceAuth.scope) + .AddClaim("grant_type", deviceAuth.grant_type); + } + + public static JwtBuilder AddClaims(this JwtBuilder builder, PinAuth pinPayload) + { + return builder + .AddClaim("client_id", pinPayload.client_id) + .AddClaim("device_id", pinPayload.device_id) + .AddClaim("credential", pinPayload.credential) + .AddClaim("credential_type", pinPayload.credential_type) + .AddClaim("nonce", pinPayload.nonce) + .AddClaim("timestamp", pinPayload.timestamp) + .AddClaim("scope", pinPayload.scope); + } + } +} diff --git a/NOnStar/NOnStar.csproj b/NOnStar/NOnStar.csproj new file mode 100644 index 0000000..5511535 --- /dev/null +++ b/NOnStar/NOnStar.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp2.0 + NOnStar + + + + + + + diff --git a/NOnStar/OnStarClient.cs b/NOnStar/OnStarClient.cs new file mode 100644 index 0000000..9c3bda9 --- /dev/null +++ b/NOnStar/OnStarClient.cs @@ -0,0 +1,266 @@ +using NOnStar.Types; +using JWT; +using JWT.Algorithms; +using JWT.Builder; +using JWT.Serializers; +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Linq; +using NOnStar.CommandAndControl; + +namespace NOnStar +{ + public class OnStarClient + { + static string ClientId = "OMB_CVY_AND_3D0"; + static string JwtSecretKey = "TAEJztOzgCYl4RyOtNvJ"; + static string DeviceId = "bf479a40-1f6a-4677-a6de-88b45a46fbae"; //Make up your own GUID + string username; + string password; + string pin; + + IJsonSerializer serializer; + IDateTimeProvider provider; + IJwtValidator validator; + IBase64UrlEncoder urlEncoder; + IJwtDecoder decoder; + HttpClient client; + Action logger = (message) => Console.WriteLine(message); + + public OnStarClient(string username, string password, string pin) + { + this.username = username; + this.password = password; + this.pin = pin; + + serializer = new JsonNetSerializer(); + provider = new UtcDateTimeProvider(); + validator = new JwtValidator(serializer, provider); + urlEncoder = new JwtBase64UrlEncoder(); + decoder = new JwtDecoder(serializer, validator, urlEncoder); + } + + public void SetupLogging(Action logger) + { + this.logger = logger; + } + + #region Public Interface + public async Task StartVehical() + { + return await RequestCommand(KnownCommand.Start); + } + + public async Task StopVehical() + { + return await RequestCommand(KnownCommand.CancelStart); + } + + public async Task LockVehical() + { + return await RequestCommand(KnownCommand.LockDoor); + } + + public async Task UnlockVehical() + { + return await RequestCommand(KnownCommand.UnlockDoor); + } + + #endregion + + //Model: Request command maps input command to type received from server, then Triggers command which involves monitoring it's success + private async Task RequestCommand(KnownCommand command) + { + try + { + var loginResponse = await LogInAndGetDetailedVehicalInfo(); + var detailedVehicalInfoStatus = loginResponse as CommandRequestStatus; + + if (detailedVehicalInfoStatus == null || detailedVehicalInfoStatus.Successful == false) + { + return loginResponse; + } + else + { + var startCommand = detailedVehicalInfoStatus.Content.vehicle.commands.command.FirstOrDefault(c => c.name == command); + await TriggerCommand(startCommand); + } + } + catch (Exception ex) + { + logger($"Failure executing command {command.Key} - {ex}"); + } + + return CommandRequestStatus.GetSuccessful(); + } + + private async Task> LogInAndGetDetailedVehicalInfo() + { + var authObject = new DeviceAuth() + { + client_id = ClientId, + device_id = DeviceId, + grant_type = "password", + username = username, + password = password, + }; + + CreateHttClient(); + + var loginResponse = await Login(authObject); + if (loginResponse.Successful == false) + { + return CommandRequestStatus.GetFailed(loginResponse.ErrorMessage); + } + + logger("Getting vehicals..."); + var getResponse = await client.GetAsync("https://api.gm.com/api/v1/account/vehicles"); + var responseBody = await getResponse.Content.ReadAsStringAsync(); + var vehicals = serializer.Deserialize(responseBody); + + var firstCar = vehicals.vehicles.vehicle.First(); + + logger($"Getting detailed info on {firstCar.vin}"); + var vehicalDetailsReply = await client.GetAsync($"https://api.gm.com/api/v1/account/vehicles/{firstCar.vin}?includeCommands=true&includeFeatures=true&includeDealers=true&includeCarrierAccount=true"); + var vehicalDetailsString = await vehicalDetailsReply.Content.ReadAsStringAsync(); + var detailedVehicalInfo = serializer.Deserialize(vehicalDetailsString); + foreach (var item in detailedVehicalInfo.vehicle.commands.command) + { + logger(item.name); + logger(item.description); + } + + return CommandRequestStatus.GetSuccessful(detailedVehicalInfo); + } + + private async Task TriggerCommand(Command command) + { + if (command.isPrivSessionRequired == true) + { + await Upgrade(); + } + + var monitoringUrl = await ExecuteCommand(command); + + await MonitorCommand(monitoringUrl); + } + + private async Task ExecuteCommand(Command command) + { + var content = GetStringContentBasedOnCommandType(command); + var startResult = await client.PostAsync(command.url, content); + var startResultStr = await startResult.Content.ReadAsStringAsync(); + + logger($"Command reply: {startResultStr}"); + + var commandResponse = serializer.Deserialize(startResultStr); + + return commandResponse.commandResponse.url; + } + + private async Task MonitorCommand(string monitoringUrl) + { + OuterCommandResponse commandResponse = null; + do + { + System.Threading.Thread.Sleep(5 * 1000); + var commandQueryResponse = await client.GetAsync(monitoringUrl); + var commandQueryResponseStr = await commandQueryResponse.Content.ReadAsStringAsync(); + logger(commandQueryResponseStr); + commandResponse = serializer.Deserialize(commandQueryResponseStr); + } while (commandResponse.commandResponse.status == "inProgress"); + + if( commandResponse.commandResponse.status == "failure") + { + logger(commandResponse.commandResponse.body.error.description); + + return CommandRequestStatus.GetFailed(commandResponse.commandResponse.body.error.description); + } + else + { + return CommandRequestStatus.GetSuccessful(); + } + } + + private StringContent GetStringContentBasedOnCommandType(Command command) + { + switch(command.name) + { + case "start": + case "cancelStart": + return new StringContent("{}"); + case "lockDoor": + return new StringContent("{\"lockDoorRequest\":{\"delay\":0}}"); + case "unlockDoor": + return new StringContent("{\"unlockDoorRequest\":{\"delay\":0}}"); + default: + return new StringContent("{}"); + } + } + + private async Task Upgrade() + { + var pinPayload = new PinAuth() { client_id = ClientId, credential = pin, device_id = DeviceId }; + var pinToken = new JwtBuilder() + .WithAlgorithm(new HMACSHA256Algorithm()) + .AddClaims(pinPayload) + .WithSecret(JwtSecretKey) + .Build(); + + var pinUpgradeResult = await client.PostAsync("https://api.gm.com/api/v1/oauth/token/upgrade", new StringContent(pinToken)); + var pinUpgradeResultStr = await pinUpgradeResult.Content.ReadAsStringAsync(); + } + + private async Task Login( DeviceAuth authObject) + { + var loginToken = new JwtBuilder() + .WithAlgorithm(new HMACSHA256Algorithm()) + .AddClaims(authObject) + .WithSecret(JwtSecretKey) + .Build(); + + logger("Logging in..."); + var result = await client.PostAsync("https://api.gm.com/api/v1/oauth/token", new StringContent(loginToken)); + + var loginResponse = await result.Content.ReadAsStringAsync(); + logger($"Response Token: {loginResponse}"); + + if(loginResponse.Contains("error")) + { + var loginErrorResponse = serializer.Deserialize(loginResponse); + return new CommandRequestStatus() { Successful = false, ErrorMessage = loginErrorResponse.error }; + } + + logger(decoder.Decode(loginResponse, JwtSecretKey, verify: true)); + var json = decoder.DecodeToObject(loginResponse, JwtSecretKey, verify: true); + + AddAccessToken(json); + + return new CommandRequestStatus() { Successful = true}; + } + + private void AddAccessToken(LoginReply json) + { + logger($"Token found: {json.access_token}"); + client.DefaultRequestHeaders.Add("Authorization", $"Bearer {json.access_token}"); + } + + private void CreateHttClient() + { + client = new HttpClient(); + client.DefaultRequestHeaders.Clear(); + client.DefaultRequestHeaders.Add("Accept", "application/json"); + client.DefaultRequestHeaders.Add("Accept-Language", "en"); + client.DefaultRequestHeaders.Add("Host", "api.gm.com"); + client.DefaultRequestHeaders.Add("Connection", "close"); + client.DefaultRequestHeaders.Add("User-Agent", "okhttp/3.9.0"); + + ServicePointManager.Expect100Continue = true; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + } + } +} diff --git a/NOnStar/Types/Address.cs b/NOnStar/Types/Address.cs new file mode 100644 index 0000000..848b30b --- /dev/null +++ b/NOnStar/Types/Address.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Address + { + public string addressLine1 { get; set; } + public string city { get; set; } + public string provinceOrStateCode { get; set; } + public string countryCode { get; set; } + public string postalCode { get; set; } + } +} diff --git a/NOnStar/Types/Command.cs b/NOnStar/Types/Command.cs new file mode 100644 index 0000000..906f288 --- /dev/null +++ b/NOnStar/Types/Command.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Command + { + public string name { get; set; } + public string description { get; set; } + public string url { get; set; } + public bool isPrivSessionRequired { get; set; } + } +} diff --git a/NOnStar/Types/Commands.cs b/NOnStar/Types/Commands.cs new file mode 100644 index 0000000..475d20d --- /dev/null +++ b/NOnStar/Types/Commands.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Commands + { + public List command { get; set; } + } +} diff --git a/NOnStar/Types/Dealer.cs b/NOnStar/Types/Dealer.cs new file mode 100644 index 0000000..9920a45 --- /dev/null +++ b/NOnStar/Types/Dealer.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Dealer + { + public string type { get; set; } + public string name { get; set; } + public string businessAssociateCode { get; set; } + public string active { get; set; } + public string phoneNo { get; set; } + public string faxNo { get; set; } + public string websiteURL { get; set; } + public Address address { get; set; } + public string dealerID { get; set; } + public string dealerCode { get; set; } + public string divisionCode { get; set; } + } +} diff --git a/NOnStar/Types/Dealers.cs b/NOnStar/Types/Dealers.cs new file mode 100644 index 0000000..f2fccbc --- /dev/null +++ b/NOnStar/Types/Dealers.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Dealers + { + public List dealer { get; set; } + } +} diff --git a/NOnStar/Types/DetailedVehialInfo.cs b/NOnStar/Types/DetailedVehialInfo.cs new file mode 100644 index 0000000..60d44e0 --- /dev/null +++ b/NOnStar/Types/DetailedVehialInfo.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class DetailedVehialInfo + { + public Vehicle vehicle { get; set; } + } +} diff --git a/NOnStar/Types/Features.cs b/NOnStar/Types/Features.cs new file mode 100644 index 0000000..2d31c43 --- /dev/null +++ b/NOnStar/Types/Features.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Features + { + public List feature { get; set; } + } +} diff --git a/NOnStar/Types/InsuranceAgent.cs b/NOnStar/Types/InsuranceAgent.cs new file mode 100644 index 0000000..d947f56 --- /dev/null +++ b/NOnStar/Types/InsuranceAgent.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class InsuranceAgent + { + public Phone phone { get; set; } + } +} diff --git a/NOnStar/Types/InsuranceInfo.cs b/NOnStar/Types/InsuranceInfo.cs new file mode 100644 index 0000000..7e31649 --- /dev/null +++ b/NOnStar/Types/InsuranceInfo.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class InsuranceInfo + { + public InsuranceAgent insuranceAgent { get; set; } + } +} diff --git a/NOnStar/Types/KnownCommand.cs b/NOnStar/Types/KnownCommand.cs new file mode 100644 index 0000000..03ecacb --- /dev/null +++ b/NOnStar/Types/KnownCommand.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class KnownCommand + { + public static KnownCommand CancelAlert = new KnownCommand("cancelAlert", "Cancel a vehicle alert(honk horns/flash lights)."); + public static KnownCommand LockDoor = new KnownCommand("lockDoor", "Locks the doors."); + public static KnownCommand UnlockDoor = new KnownCommand("unlockDoor", "Unlocks the doors."); + public static KnownCommand Alert = new KnownCommand("alert", "Triggers a vehicle alert (honk horns/flash lights)."); + public static KnownCommand Start = new KnownCommand("start", "Remotely starts the vehicle."); + public static KnownCommand CancelStart = new KnownCommand("cancelStart", "Cancels previous remote start command."); + public static KnownCommand SendNavDestination = new KnownCommand("sendNavDestination", "Calculate route and send it to the vehicle's nav unit."); + public static KnownCommand Connect = new KnownCommand("connect", "Initiates a connection to the vehicle"); + public static KnownCommand EnableTelemetry = new KnownCommand("enableTelemetry", "Enrolls a vehicle in telemetry."); + public static KnownCommand DisableTelemetry = new KnownCommand("disableTelemetry", "Unenrolls a vehicle from telemetry.."); + + public string Key { get; set; } + public string Description { get; set; } + + private KnownCommand(string key, string description) + { + this.Key = key; + this.Description = description; + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public static bool operator==(string key, KnownCommand command) + { + return key == command.Key; + } + + public static bool operator !=(string key, KnownCommand command) + { + return key != command.Key; + } + + public static bool operator ==(KnownCommand command, string key) + { + return key == command.Key; + } + + public static bool operator !=(KnownCommand command, string key) + { + return key != command.Key; + } + } +} diff --git a/NOnStar/Types/LicensePlate.cs b/NOnStar/Types/LicensePlate.cs new file mode 100644 index 0000000..634b8b2 --- /dev/null +++ b/NOnStar/Types/LicensePlate.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class LicensePlate + { + public string plateNumber { get; set; } + public string country { get; set; } + public string provinceOrStateCode { get; set; } + } +} diff --git a/NOnStar/Types/LoginError.cs b/NOnStar/Types/LoginError.cs new file mode 100644 index 0000000..1b4c02e --- /dev/null +++ b/NOnStar/Types/LoginError.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class LoginError + { + public string error { get; set; } + } +} diff --git a/NOnStar/Types/LoginReply.cs b/NOnStar/Types/LoginReply.cs new file mode 100644 index 0000000..35aeced --- /dev/null +++ b/NOnStar/Types/LoginReply.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class LoginReply + { + public string access_token { get; set; } + public string token_type { get; set; } + public int expires_in { get; set; } + public string scope { get; set; } + public OnstarAccountInfo onstar_account_info { get; set; } + public UserInfo user_info { get; set; } + public string id_token { get; set; } + } +} diff --git a/NOnStar/Types/OnstarAccountInfo.cs b/NOnStar/Types/OnstarAccountInfo.cs new file mode 100644 index 0000000..b9cb804 --- /dev/null +++ b/NOnStar/Types/OnstarAccountInfo.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class OnstarAccountInfo + { + public string country_code { get; set; } + public string account_no { get; set; } + } +} diff --git a/NOnStar/Types/Phone.cs b/NOnStar/Types/Phone.cs new file mode 100644 index 0000000..e7d08ef --- /dev/null +++ b/NOnStar/Types/Phone.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Phone + { + } +} diff --git a/NOnStar/Types/UserInfo.cs b/NOnStar/Types/UserInfo.cs new file mode 100644 index 0000000..261eb3e --- /dev/null +++ b/NOnStar/Types/UserInfo.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class UserInfo + { + public string RemoteUserId { get; set; } + public string country { get; set; } + } +} diff --git a/NOnStar/Types/VehicalList.cs b/NOnStar/Types/VehicalList.cs new file mode 100644 index 0000000..ab45362 --- /dev/null +++ b/NOnStar/Types/VehicalList.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class VehicalList + { + public Vehicles vehicles { get; set; } + } +} diff --git a/NOnStar/Types/Vehicle.cs b/NOnStar/Types/Vehicle.cs new file mode 100644 index 0000000..cc63f4d --- /dev/null +++ b/NOnStar/Types/Vehicle.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Vehicle + { + public string vin { get; set; } + public string make { get; set; } + public string model { get; set; } + public string year { get; set; } + public string manufacturer { get; set; } + public string phone { get; set; } + public string unitType { get; set; } + public string onstarStatus { get; set; } + public string url { get; set; } + public string isInPreActivation { get; set; } + public LicensePlate licensePlate { get; set; } + public InsuranceInfo insuranceInfo { get; set; } + public string enrolledInContinuousCoverage { get; set; } + public Commands commands { get; set; } + public Features features { get; set; } + public Dealers dealers { get; set; } + public string propulsionType { get; set; } + } +} diff --git a/NOnStar/Types/Vehicles.cs b/NOnStar/Types/Vehicles.cs new file mode 100644 index 0000000..405d165 --- /dev/null +++ b/NOnStar/Types/Vehicles.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NOnStar.Types +{ + class Vehicles + { + public string size { get; set; } + public List vehicle { get; set; } + } +}