Skip to content

Instantly share code, notes, and snippets.

@tewilove
Created August 22, 2015 04:19
Show Gist options
  • Save tewilove/75f63e1ecf708d07bea6 to your computer and use it in GitHub Desktop.
Save tewilove/75f63e1ecf708d07bea6 to your computer and use it in GitHub Desktop.
/*
*
* SHARP shdiag mode
* tewilove@gmail.com, All rights reserved
*
*/
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef __MINGW32__
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif
#include <errno.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <libusb-1.0/libusb.h>
#define USB_VID 0x04dd
#define USB_PID 0x933a
static libusb_context *g_ctx;
static int fldr_init() {
int rc;
rc = libusb_init(&g_ctx);
return rc;
}
static void fldr_free() {
libusb_exit(g_ctx);
}
// see lsusb -v -d 04dd:933a
static libusb_device_handle *fldr_open() {
int rc;
libusb_device_handle *h;
h = libusb_open_device_with_vid_pid(g_ctx, USB_VID, USB_PID);
if (!h)
return NULL;
rc = libusb_claim_interface(h, 1);
if (rc) {
// fprintf(stderr, "%04d:%s: %s(%d)\n", __LINE__, "libusb_claim_interface", libusb_error_name(rc), rc);
goto fail;
}
rc = libusb_set_interface_alt_setting(h, 1, 1);
if (rc) {
// fprintf(stderr, "%04d:%s: %s(%d)\n", __LINE__, "libusb_set_interface_alt_setting", libusb_error_name(rc), rc);
goto fail;
}
return h;
fail:
libusb_close(h);
return NULL;
}
static int fldr_close(libusb_device_handle *h) {
int rc;
rc = libusb_release_interface(h, 1);
libusb_close(h);
return rc;
}
size_t fldr_read(libusb_device_handle *h, char *buff, size_t size) {
int rc;
size_t nbtr = 0;
libusb_device *d;
int ps;
d = libusb_get_device(h);
if (!d)
return (size_t)(-1);
ps = libusb_get_max_packet_size(d, 0x81);
if (ps <= 0)
ps = 512;
while (nbtr < size) {
int nb, ch;
ch = size - nbtr;
if (ch > ps)
ch = ps;
rc = libusb_bulk_transfer(
h,
0x81,
(unsigned char *) buff + nbtr,
ch,
&nb,
1000);
if (rc) {
// fprintf(stderr, "%04d:%s: %s(%d)\n", __LINE__, __func__, libusb_error_name(rc), rc);
break;
}
nbtr += nb;
}
// fprintf(stderr, "%s: %d\n", __func__, (int) nbtr);
return nbtr;
}
size_t fldr_write(libusb_device_handle *h, const char *buff, size_t size) {
int rc;
size_t nbtr = 0;
libusb_device *d;
int ps;
d = libusb_get_device(h);
if (!d)
return (size_t)(-1);
ps = libusb_get_max_packet_size(d, 0x01);
if (ps <= 0)
ps = 512;
while (nbtr < size) {
int nb, ch;
ch = size - nbtr;
if (ch > ps)
ch = ps;
rc = libusb_bulk_transfer(
h,
0x01,
(unsigned char *) buff + nbtr,
ch,
&nb,
1000);
if (rc) {
// fprintf(stderr, "%04d:%s: %s(%d)\n", __LINE__, __func__, libusb_error_name(rc), rc);
break;
}
nbtr += nb;
}
// fprintf(stderr, "%s: %d\n", __func__, (int) nbtr);
return nbtr;
}
static int shdiag_xchar(int c) {
int i;
char xft[8] = { 0, 2, 4, 6, 1, 3, 5, 7 };
int r = 0;
for (i = 0; i < 8; i++) {
r |= (((c >> i) & 1) << xft[i]);
}
return r;
}
static int shdiag_encode_data(const char *in, size_t *is, char *out, size_t os) {
size_t ip = 0, op = 1;
int x, v;
if (os < *is / 2)
return -1;
srand(time(NULL));
v = (rand() & 0x7f) + 0xf;
x = shdiag_xchar(v);
out[0] = v;
while (ip < *is) {
if (in[ip] == '\r' || in[ip] == '\n') {
out[op++] = in[ip];
if (in[ip] == '\n' && ip + 1 < *is) {
x = shdiag_xchar(v);
out[op] = v;
op += 1;
}
} else {
out[op++] = (in[ip] ^ (x & 0x7f)) + 0xf;
x = (x >> 1) | ((x & 1) << 7);
}
ip += 1;
}
*is = op;
return 0;
}
static int shdiag_decode_data(const char *in, size_t *is, char *out, size_t os) {
size_t ip = 1, op = 0;
int x;
if (os < *is - 1)
return -1;
x = in[0];
x = shdiag_xchar(x);
while (ip < *is) {
if (in[ip] == '\r' || in[ip] == '\n') {
out[op++] = in[ip];
if (in[ip] == '\n' && ip + 1 < *is) {
x = in[ip + 1];
x = shdiag_xchar(x);
ip += 1;
}
} else {
out[op++] = (in[ip] - 0xf) ^ (x & 0x7f);
x = (x >> 1) | ((x & 1) << 7);
}
ip += 1;
}
*is = op;
return 0;
}
int main(int argc, char *argv[]) {
int rc, ret = -1;
struct libusb_device_handle *h;
char req[1024], res[1024];
char req_enc[1024], res_dec[1024];
size_t size;
size_t nbtr;
if (argc != 2)
return 1;
rc = fldr_init();
if (rc)
goto fail_fldr_init;
while (1) {
h = fldr_open();
if (h)
break;
}
nbtr = fldr_read(h, res, sizeof(res));
if (nbtr) {
memset(res_dec, 0, sizeof(res_dec));
size = nbtr;
rc = shdiag_decode_data(res, &size, res_dec, sizeof(res_dec));
if (rc)
goto fail_shdiag_decode_data;
res_dec[size] = 0;
// OK\r\nREADY\r\n
printf("%s", res_dec);
}
snprintf(req, sizeof(req), "%s\r\n", argv[1]);
size = strlen(argv[1]) + 2;
rc = shdiag_encode_data(req, &size, req_enc, sizeof(req_enc));
if (rc)
goto fail_shdiag_encode_data;
if (size && fldr_write(h, req_enc, size) == size) {
memset(res, 0, sizeof(res));
nbtr = fldr_read(h, res, sizeof(res));
if (nbtr) {
size = nbtr;
rc = shdiag_decode_data(res, &size, res_dec, sizeof(res_dec));
if (rc)
goto fail_shdiag_decode_data;
res_dec[size] = 0;
printf("%s", res_dec);
}
}
fail_shdiag_decode_data:
fail_shdiag_encode_data:
fldr_close(h);
//fail_fldr_open:
fldr_free();
fail_fldr_init:
return ret;
}
@ttlover201212
Copy link

It seems that I should disassemble the phone and look for the "test gpio",any other better solution ?

@ttlover201212
Copy link

When testing on sharp 403SH,
h = libusb_open_device_with_vid_pid(g_ctx, USB_VID, USB_PID);
Always return 0.
I have compiled different version of libusb,no help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment