LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPiAKICoKICovCgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJkb3RfY29tbWFuZC5oIgoKLyoqCiAqIERpc3BhdGNoIGFuIGluY29taW5nIG1lc3NhZ2UgdG8gdGhlIHNwZWNpZmljIGhhbmRsZXIgZm9yIHRoZSBtZXNzYWdlLgogKiBDYWxsZWQgZnJvbSBpbnRlcnJ1cHQgY29udGV4dC4KICovCnZvaWQgaWJtYXNtX3JlY2VpdmVfbWVzc2FnZShzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCB2b2lkICptZXNzYWdlLCBpbnQgbWVzc2FnZV9zaXplKQp7Cgl1MzIgc2l6ZTsKCXN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKmhlYWRlciA9IChzdHJ1Y3QgZG90X2NvbW1hbmRfaGVhZGVyICopbWVzc2FnZTsKCglzaXplID0gZ2V0X2RvdF9jb21tYW5kX3NpemUobWVzc2FnZSk7CglpZiAoc2l6ZSA+IG1lc3NhZ2Vfc2l6ZSkKCQlzaXplID0gbWVzc2FnZV9zaXplOwoKCXN3aXRjaCAoaGVhZGVyLT50eXBlKSB7CgljYXNlIHNwX2V2ZW50OiAKCQlpYm1hc21fcmVjZWl2ZV9ldmVudChzcCwgbWVzc2FnZSwgc2l6ZSk7CgkJYnJlYWs7CgljYXNlIHNwX2NvbW1hbmRfcmVzcG9uc2U6CgkJaWJtYXNtX3JlY2VpdmVfY29tbWFuZF9yZXNwb25zZShzcCwgbWVzc2FnZSwgc2l6ZSk7IAoJCWJyZWFrOwoJY2FzZSBzcF9oZWFydGJlYXQ6CgkJaWJtYXNtX3JlY2VpdmVfaGVhcnRiZWF0KHNwLCBtZXNzYWdlLCBzaXplKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJZGV2X2VycihzcC0+ZGV2LCAiUmVjZWl2ZWQgdW5rbm93biBtZXNzYWdlIGZyb20gc2VydmljZSBwcm9jZXNzb3JcbiIpOwoJfQp9CgoKI2RlZmluZSBJTklUX0JVRkZFUl9TSVpFIDMyCgoKLyoqCiAqIHNlbmQgdGhlIDQuMy41LjEwIGRvdCBjb21tYW5kIChkcml2ZXIgVlBEKSB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IKICovCmludCBpYm1hc21fc2VuZF9kcml2ZXJfdnBkKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCXN0cnVjdCBjb21tYW5kICpjb21tYW5kOwoJc3RydWN0IGRvdF9jb21tYW5kX2hlYWRlciAqaGVhZGVyOwoJdTggKnZwZF9jb21tYW5kOwoJdTggKnZwZF9kYXRhOwoJaW50IHJlc3VsdCA9IDA7CgoJY29tbWFuZCA9IGlibWFzbV9uZXdfY29tbWFuZChJTklUX0JVRkZFUl9TSVpFKTsKCWlmIChjb21tYW5kID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJaGVhZGVyID0gKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKiljb21tYW5kLT5idWZmZXI7CgloZWFkZXItPnR5cGUgICAgICAgICAgICAgICAgPSBzcF93cml0ZTsKCWhlYWRlci0+Y29tbWFuZF9zaXplICAgICAgICA9IDQ7CgloZWFkZXItPmRhdGFfc2l6ZSAgICAgICAgICAgPSAxNjsKCWhlYWRlci0+c3RhdHVzICAgICAgICAgICAgICA9IDA7CgloZWFkZXItPnJlc2VydmVkICAgICAgICAgICAgPSAwOwoKCXZwZF9jb21tYW5kID0gY29tbWFuZC0+YnVmZmVyICsgc2l6ZW9mKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIpOwoJdnBkX2NvbW1hbmRbMF0gPSAweDQ7Cgl2cGRfY29tbWFuZFsxXSA9IDB4MzsKCXZwZF9jb21tYW5kWzJdID0gMHg1OwoJdnBkX2NvbW1hbmRbM10gPSAweGE7CgoJdnBkX2RhdGEgPSB2cGRfY29tbWFuZCArIGhlYWRlci0+Y29tbWFuZF9zaXplOwoJdnBkX2RhdGFbMF0gPSAwOwoJc3RyY2F0KHZwZF9kYXRhLCBJQk1BU01fRFJJVkVSX1ZQRCk7Cgl2cGRfZGF0YVsxMF0gPSAwOwoJdnBkX2RhdGFbMTVdID0gMDsKCQoJaWJtYXNtX2V4ZWNfY29tbWFuZChzcCwgY29tbWFuZCk7CglpYm1hc21fd2FpdF9mb3JfcmVzcG9uc2UoY29tbWFuZCwgSUJNQVNNX0NNRF9USU1FT1VUX05PUk1BTCk7CgoJaWYgKGNvbW1hbmQtPnN0YXR1cyAhPSBJQk1BU01fQ01EX0NPTVBMRVRFKQoJCXJlc3VsdCA9IC1FTk9ERVY7CgoJY29tbWFuZF9wdXQoY29tbWFuZCk7CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RydWN0IG9zX3N0YXRlX2NvbW1hbmQgewoJc3RydWN0IGRvdF9jb21tYW5kX2hlYWRlcgloZWFkZXI7Cgl1bnNpZ25lZCBjaGFyCQkJY29tbWFuZFszXTsKCXVuc2lnbmVkIGNoYXIJCQlkYXRhOwp9OwoKLyoqCiAqIHNlbmQgdGhlIDQuMy42IGRvdCBjb21tYW5kIChvcyBzdGF0ZSkgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqIER1cmluZyBkcml2ZXIgaW5pdCB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIG9zIHN0YXRlICJ1cCIuCiAqIFRoaXMgY2F1c2VzIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciB0byBzdGFydCBzZW5kaW5nIGhlYXJ0YmVhdHMgdGhlCiAqIGRyaXZlci4KICogRHVyaW5nIGRyaXZlciBleGl0IHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCBvcyBzdGF0ZSAiZG93biIsIAogKiBjYXVzaW5nIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciB0byBzdG9wIHRoZSBoZWFydGJlYXRzLgogKi8KaW50IGlibWFzbV9zZW5kX29zX3N0YXRlKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIGludCBvc19zdGF0ZSkKewoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCXN0cnVjdCBvc19zdGF0ZV9jb21tYW5kICpvc19zdGF0ZV9jbWQ7CglpbnQgcmVzdWx0ID0gMDsKCgljbWQgPSBpYm1hc21fbmV3X2NvbW1hbmQoc2l6ZW9mKHN0cnVjdCBvc19zdGF0ZV9jb21tYW5kKSk7CglpZiAoY21kID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJb3Nfc3RhdGVfY21kID0gKHN0cnVjdCBvc19zdGF0ZV9jb21tYW5kICopY21kLT5idWZmZXI7Cglvc19zdGF0ZV9jbWQtPmhlYWRlci50eXBlCQk9IHNwX3dyaXRlOwoJb3Nfc3RhdGVfY21kLT5oZWFkZXIuY29tbWFuZF9zaXplCT0gMzsKCW9zX3N0YXRlX2NtZC0+aGVhZGVyLmRhdGFfc2l6ZQkJPSAxOwoJb3Nfc3RhdGVfY21kLT5oZWFkZXIuc3RhdHVzCQk9IDA7Cglvc19zdGF0ZV9jbWQtPmNvbW1hbmRbMF0JCT0gNDsKCW9zX3N0YXRlX2NtZC0+Y29tbWFuZFsxXQkJPSAzOwoJb3Nfc3RhdGVfY21kLT5jb21tYW5kWzJdCQk9IDY7Cglvc19zdGF0ZV9jbWQtPmRhdGEJCQk9IG9zX3N0YXRlOwoKCWlibWFzbV9leGVjX2NvbW1hbmQoc3AsIGNtZCk7CglpYm1hc21fd2FpdF9mb3JfcmVzcG9uc2UoY21kLCBJQk1BU01fQ01EX1RJTUVPVVRfTk9STUFMKTsKCglpZiAoY21kLT5zdGF0dXMgIT0gSUJNQVNNX0NNRF9DT01QTEVURSkKCQlyZXN1bHQgPSAtRU5PREVWOwoKCWNvbW1hbmRfcHV0KGNtZCk7CglyZXR1cm4gcmVzdWx0Owp9Cg==