public byte[] ToBytes() { byte[] deviceToken = new byte[DeviceToken.Length / 2]; for (int i = 0; i < deviceToken.Length; i++) { deviceToken[i] = byte.Parse(DeviceToken.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } if (deviceToken.Length != DEVICE_TOKEN_BINARY_SIZE) { throw new BadDeviceTokenException(DeviceToken); } byte[] deviceTokenSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(deviceToken.Length))); byte[] payload = Encoding.UTF8.GetBytes(Payload.ToJson()); if (payload.Length > MAX_PAYLOAD_SIZE) { int newSize = Payload.Alert.Body.Length - (payload.Length - MAX_PAYLOAD_SIZE); if (newSize > 0) { Payload.Alert.Body = Payload.Alert.Body.Substring(0, newSize); payload = Encoding.UTF8.GetBytes(Payload.ToString()); } else { do { Payload.Alert.Body = Payload.Alert.Body.Remove(Payload.Alert.Body.Length - 1); payload = Encoding.UTF8.GetBytes(Payload.ToString()); }while (payload.Length > MAX_PAYLOAD_SIZE && !string.IsNullOrEmpty(Payload.Alert.Body)); } if (payload.Length > MAX_PAYLOAD_SIZE) { throw new NotificationLengthException(this); } } byte[] payloadSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(payload.Length))); int bufferSize = sizeof(Byte) + deviceTokenSize.Length + deviceToken.Length + payloadSize.Length + payload.Length; byte[] buffer = new byte[bufferSize]; buffer[0] = 0x00; Buffer.BlockCopy(deviceTokenSize, 0, buffer, sizeof(Byte), deviceTokenSize.Length); Buffer.BlockCopy(deviceToken, 0, buffer, sizeof(Byte) + deviceTokenSize.Length, deviceToken.Length); Buffer.BlockCopy(payloadSize, 0, buffer, sizeof(Byte) + deviceTokenSize.Length + deviceToken.Length, payloadSize.Length); Buffer.BlockCopy(payload, 0, buffer, sizeof(Byte) + deviceTokenSize.Length + deviceToken.Length + payloadSize.Length, payload.Length); return(buffer); }
public byte[] ToBytes() { // Without reading the response which would make any identifier useful, it seems silly to // expose the value in the object model, although that would be easy enough to do. For // now we'll just use zero. int identifier = 0; byte[] identifierBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(identifier)); // APNS will not store-and-forward a notification with no expiry, so set it one year in the future // if the client does not provide it. int expiryTimeStamp = -1; if (Expiration != DoNotStore) { DateTime concreteExpireDateUtc = (Expiration ?? DateTime.UtcNow.AddMonths(1)).ToUniversalTime(); TimeSpan epochTimeSpan = concreteExpireDateUtc - UNIX_EPOCH; expiryTimeStamp = (int)epochTimeSpan.TotalSeconds; } byte[] expiry = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(expiryTimeStamp)); byte[] deviceToken = new byte[DeviceToken.Length / 2]; for (int i = 0; i < deviceToken.Length; i++) { deviceToken[i] = byte.Parse(DeviceToken.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } if (deviceToken.Length != DEVICE_TOKEN_BINARY_SIZE) { throw new BadDeviceTokenException(DeviceToken); } byte[] deviceTokenSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(deviceToken.Length))); byte[] payload = Encoding.UTF8.GetBytes(Payload.ToJson()); if (payload.Length > MAX_PAYLOAD_SIZE) { int newSize = Payload.Alert.Body.Length - (payload.Length - MAX_PAYLOAD_SIZE); if (newSize > 0) { Payload.Alert.Body = Payload.Alert.Body.Substring(0, newSize); payload = Encoding.UTF8.GetBytes(Payload.ToString()); } else { do { Payload.Alert.Body = Payload.Alert.Body.Remove(Payload.Alert.Body.Length - 1); payload = Encoding.UTF8.GetBytes(Payload.ToString()); }while (payload.Length > MAX_PAYLOAD_SIZE && !string.IsNullOrEmpty(Payload.Alert.Body)); } if (payload.Length > MAX_PAYLOAD_SIZE) { throw new NotificationLengthException(this); } } byte[] payloadSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(payload.Length))); int bufferSize = sizeof(Byte) + deviceTokenSize.Length + deviceToken.Length + payloadSize.Length + payload.Length; byte[] buffer = new byte[bufferSize]; List <byte[]> notificationParts = new List <byte[]>(); notificationParts.Add(new byte[] { 0x01 }); // Enhanced notification format command notificationParts.Add(identifierBytes); notificationParts.Add(expiry); notificationParts.Add(deviceTokenSize); notificationParts.Add(deviceToken); notificationParts.Add(payloadSize); notificationParts.Add(payload); return(BuildBufferFrom(notificationParts)); }
public byte[] ToBytes() { var builder = new List <byte> (); // 1 - Device Token if (string.IsNullOrEmpty(this.DeviceToken)) { throw new NotificationException("Missing DeviceToken", this); } if (!IsDeviceRegistrationIdValid()) { throw new NotificationException("Invalid DeviceToken", this); } // Turn the device token into bytes byte[] deviceToken = new byte[DeviceToken.Length / 2]; for (int i = 0; i < deviceToken.Length; i++) { try { deviceToken [i] = byte.Parse(DeviceToken.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } catch (Exception) { throw new NotificationException("Invalid DeviceToken", this); } } if (deviceToken.Length < DEVICE_TOKEN_BINARY_MIN_SIZE) { throw new NotificationException("Invalid DeviceToken Length", this); } builder.Add(0x01); // Device Token ID builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(deviceToken.Length)))); builder.AddRange(deviceToken); // 2 - Payload var payload = Encoding.UTF8.GetBytes(ToString()); if (payload.Length > MAX_PAYLOAD_SIZE) { throw new NotificationException("Payload too large (must be " + MAX_PAYLOAD_SIZE + " bytes or smaller", this); } builder.Add(0x02); // Payload ID builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(payload.Length)))); builder.AddRange(payload); // 3 - Identifier builder.Add(0x03); builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int16)4))); builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Identifier))); // 4 - Expiration // APNS will not store-and-forward a notification with no expiry, so set it one year in the future // if the client does not provide it. int expiryTimeStamp = -1; if (Expiration != DoNotStore) { DateTime concreteExpireDateUtc = (Expiration ?? DateTime.UtcNow.AddMonths(1)).ToUniversalTime(); TimeSpan epochTimeSpan = concreteExpireDateUtc - UNIX_EPOCH; expiryTimeStamp = (int)epochTimeSpan.TotalSeconds; } builder.Add(0x04); // 4 - Expiry ID builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int16)4))); builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(expiryTimeStamp))); // 5 - Priority //TODO: Add priority var priority = LowPriority ? (byte)5 : (byte)10; builder.Add(0x05); // 5 - Priority builder.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int16)1))); builder.Add(priority); var frameLength = builder.Count; builder.Insert(0, 0x02); // COMMAND 2 for new format // Insert the frame length builder.InsertRange(1, BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int32)frameLength))); return(builder.ToArray()); }