-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic MCS implementation to realize C2DM (used by GCM)
- Can be started using `am startservice com.google.android.gms/org.microg.gms.gcm.mcs.McsService` on device - Does not send Heartbeats -> Connection will be closed after 30 minutes - No automatic reconnect on connection closure - Only push, no bidirectional communication
- Loading branch information
Showing
21 changed files
with
2,935 additions
and
0 deletions.
There are no files selected for viewing
28 changes: 28 additions & 0 deletions
28
play-services-core/src/main/java/org/microg/gms/gcm/mcs/Constants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright 2013-2015 µg Project Team | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.microg.gms.gcm.mcs; | ||
|
||
public class Constants { | ||
public static final int MCS_HEARTBEAT_ACK_TAG = 1; | ||
public static final int MCS_LOGIN_REQUEST_TAG = 2; | ||
public static final int MCS_LOGIN_RESPONSE_TAG = 3; | ||
public static final int MCS_CLOSE_TAG = 4; | ||
public static final int MCS_IQ_STANZA_TAG = 7; | ||
public static final int MCS_DATA_MESSAGE_STANZA_TAG = 8; | ||
|
||
public static final int MCS_VERSION_CODE = 41; | ||
} |
127 changes: 127 additions & 0 deletions
127
play-services-core/src/main/java/org/microg/gms/gcm/mcs/McsInputStream.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
* Copyright 2013-2015 µg Project Team | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.microg.gms.gcm.mcs; | ||
|
||
import android.util.Base64; | ||
import android.util.Log; | ||
|
||
import com.squareup.wire.Message; | ||
import com.squareup.wire.Wire; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
import static org.microg.gms.gcm.mcs.Constants.MCS_CLOSE_TAG; | ||
import static org.microg.gms.gcm.mcs.Constants.MCS_DATA_MESSAGE_STANZA_TAG; | ||
import static org.microg.gms.gcm.mcs.Constants.MCS_HEARTBEAT_ACK_TAG; | ||
import static org.microg.gms.gcm.mcs.Constants.MCS_IQ_STANZA_TAG; | ||
import static org.microg.gms.gcm.mcs.Constants.MCS_LOGIN_REQUEST_TAG; | ||
import static org.microg.gms.gcm.mcs.Constants.MCS_LOGIN_RESPONSE_TAG; | ||
|
||
public class McsInputStream { | ||
private static final String TAG = "GmsGcmMcsInput"; | ||
|
||
private final InputStream is; | ||
private boolean initialized; | ||
private int version = -1; | ||
private int lastStreamIdReported = -1; | ||
private int streamId = 0; | ||
|
||
public McsInputStream(InputStream is) { | ||
this(is, false); | ||
} | ||
|
||
public McsInputStream(InputStream is, boolean initialized) { | ||
this.is = is; | ||
this.initialized = initialized; | ||
} | ||
|
||
public int getStreamId() { | ||
lastStreamIdReported = streamId; | ||
return streamId; | ||
} | ||
|
||
public boolean newStreamIdAvailable() { | ||
return lastStreamIdReported != streamId; | ||
} | ||
|
||
public int getVersion() { | ||
ensureVersionRead(); | ||
return version; | ||
} | ||
|
||
private void ensureVersionRead() { | ||
if (!initialized) { | ||
try { | ||
version = is.read(); | ||
Log.d(TAG, "Reading from MCS version=" + version); | ||
initialized = true; | ||
} catch (IOException e) { | ||
Log.w(TAG, e); | ||
} | ||
} | ||
} | ||
|
||
public synchronized Message read() throws IOException { | ||
ensureVersionRead(); | ||
int mcsTag = is.read(); | ||
int mcsSize = readVarint(); | ||
Log.d(TAG, "Reading from MCS tag=" + mcsTag + " size=" + mcsSize); | ||
byte[] bytes = new byte[mcsSize]; | ||
int len = 0; | ||
while ((len += is.read(bytes, len, mcsSize - len)) < mcsSize) ; | ||
Log.d(TAG, "Reading from MCS: " + Base64.encodeToString(bytes, 0)); | ||
Message read = read(mcsTag, bytes, len); | ||
Log.d(TAG, "Read from MCS: " + read); | ||
streamId++; | ||
return read; | ||
} | ||
|
||
private static Message read(int mcsTag, byte[] bytes, int len) throws IOException { | ||
Wire wire = new Wire(); | ||
switch (mcsTag) { | ||
case MCS_HEARTBEAT_ACK_TAG: | ||
return wire.parseFrom(bytes, 0, len, HeartbeatAck.class); | ||
case MCS_LOGIN_REQUEST_TAG: | ||
return wire.parseFrom(bytes, 0, len, LoginRequest.class); | ||
case MCS_LOGIN_RESPONSE_TAG: | ||
return wire.parseFrom(bytes, 0, len, LoginResponse.class); | ||
case MCS_CLOSE_TAG: | ||
return wire.parseFrom(bytes, 0, len, Close.class); | ||
case MCS_IQ_STANZA_TAG: | ||
return wire.parseFrom(bytes, 0, len, IqStanza.class); | ||
case MCS_DATA_MESSAGE_STANZA_TAG: | ||
return wire.parseFrom(bytes, 0, len, DataMessageStanza.class); | ||
default: | ||
return null; | ||
} | ||
} | ||
|
||
private int readVarint() throws IOException { | ||
int res = 0; | ||
int s = 0; | ||
int b = 0x80; | ||
while ((b & 0x80) == 0x80) { | ||
b = is.read(); | ||
res |= (b & 0x7F) << s; | ||
s += 7; | ||
} | ||
return res; | ||
} | ||
|
||
|
||
} |
86 changes: 86 additions & 0 deletions
86
play-services-core/src/main/java/org/microg/gms/gcm/mcs/McsOutputStream.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright 2013-2015 µg Project Team | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.microg.gms.gcm.mcs; | ||
|
||
import android.util.Log; | ||
|
||
import com.squareup.wire.Message; | ||
|
||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
|
||
import static org.microg.gms.gcm.mcs.Constants.*; | ||
|
||
public class McsOutputStream { | ||
private static final String TAG = "GmsGcmMcsOutput"; | ||
|
||
private final OutputStream os; | ||
private boolean initialized; | ||
private int version = MCS_VERSION_CODE; | ||
private int streamId = 0; | ||
|
||
public McsOutputStream(OutputStream os) { | ||
this(os, false); | ||
} | ||
|
||
public McsOutputStream(OutputStream os, boolean initialized) { | ||
this.os = os; | ||
this.initialized = initialized; | ||
} | ||
|
||
public int getStreamId() { | ||
return streamId; | ||
} | ||
|
||
public void write(DataMessageStanza message) throws IOException { | ||
write(message, MCS_DATA_MESSAGE_STANZA_TAG); | ||
} | ||
|
||
public void write(LoginRequest loginRequest) throws IOException { | ||
write(loginRequest, MCS_LOGIN_REQUEST_TAG); | ||
} | ||
|
||
public void write(HeartbeatAck ack) throws IOException { | ||
write(ack, MCS_HEARTBEAT_ACK_TAG); | ||
} | ||
|
||
public synchronized void write(Message message, int tag) throws IOException { | ||
if (!initialized) { | ||
Log.d(TAG, "Write MCS version code: " + version); | ||
os.write(version); | ||
initialized = true; | ||
} | ||
Log.d(TAG, "Write to MCS: " + message); | ||
os.write(tag); | ||
writeVarint(os, message.getSerializedSize()); | ||
os.write(message.toByteArray()); | ||
os.flush(); | ||
streamId++; | ||
} | ||
|
||
private void writeVarint(OutputStream os, int value) throws IOException { | ||
while (true) { | ||
if ((value & ~0x7FL) == 0) { | ||
os.write(value); | ||
return; | ||
} else { | ||
os.write((value & 0x7F) | 0x80); | ||
value >>>= 7; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.