49
49
50
50
#define CMD_HWINFO 0x1833
51
51
#define CMD_SWINFO 0x1834
52
- #define CMD_RANGE 0x1840
53
- #define CMD_ADDRESS 0x1841
54
- #define CMD_READ 0x1842
52
+
53
+ // Screen
54
+ #define CMD_SCREEN_RANGE 0x1840
55
+ #define CMD_SCREEN_ADDRESS 0x1841
56
+ #define CMD_SCREEN_READ 0x1842
57
+
58
+ // Tablet
59
+ #define CMD_TABLET_RANGE 0x1850
60
+ #define CMD_TABLET_ADDRESS 0x1851
61
+ #define CMD_TABLET_READ 0x1852
55
62
56
63
#define SZ_HWINFO 256
57
64
#define SZ_SWINFO 256
65
72
#define FP_OFFSET 0x0A
66
73
#define FP_SIZE 7
67
74
68
- #define RB_PROFILE_BEGIN 0x010000
69
- #define RB_PROFILE_END 0x200000
70
- #define RB_PROFILE_SIZE (RB_PROFILE_END - RB_PROFILE_BEGIN)
71
- #define RB_PROFILE_DISTANCE (a ,b ) ringbuffer_distance (a, b, DC_RINGBUFFER_FULL, RB_PROFILE_BEGIN, RB_PROFILE_END)
72
- #define RB_PROFILE_INCR (a ,d ) ringbuffer_increment (a, d, RB_PROFILE_BEGIN, RB_PROFILE_END)
75
+ #define RB_PROFILE_DISTANCE (a ,b ,l ) ringbuffer_distance (a, b, DC_RINGBUFFER_FULL, l->rb_profile_begin, l->rb_profile_end)
76
+ #define RB_PROFILE_INCR (a ,b ,l ) ringbuffer_increment (a, b, l->rb_profile_begin, l->rb_profile_end)
77
+
78
+ #define ACTION 0x01
79
+ #define SCREEN 0x02
80
+ #define TABLET 0x10
81
+
82
+ typedef struct seac_screen_commands_t {
83
+ unsigned short range ;
84
+ unsigned short address ;
85
+ unsigned short read ;
86
+ } seac_screen_commands_t ;
87
+
88
+ typedef struct seac_screen_layout_t {
89
+ unsigned int rb_profile_begin ;
90
+ unsigned int rb_profile_end ;
91
+ } seac_screen_layout_t ;
73
92
74
93
typedef struct seac_screen_device_t {
75
94
dc_device_t base ;
76
95
dc_iostream_t * iostream ;
96
+ const seac_screen_commands_t * cmds ;
97
+ const seac_screen_layout_t * layout ;
77
98
unsigned char info [SZ_HWINFO + SZ_SWINFO ];
78
99
unsigned char fingerprint [FP_SIZE ];
79
100
} seac_screen_device_t ;
@@ -100,6 +121,28 @@ static const dc_device_vtable_t seac_screen_device_vtable = {
100
121
NULL , /* close */
101
122
};
102
123
124
+ static const seac_screen_commands_t cmds_screen = {
125
+ CMD_SCREEN_RANGE ,
126
+ CMD_SCREEN_ADDRESS ,
127
+ CMD_SCREEN_READ ,
128
+ };
129
+
130
+ static const seac_screen_commands_t cmds_tablet = {
131
+ CMD_TABLET_RANGE ,
132
+ CMD_TABLET_ADDRESS ,
133
+ CMD_TABLET_READ ,
134
+ };
135
+
136
+ static const seac_screen_layout_t layout_screen = {
137
+ 0x010000 , /* rb_profile_begin */
138
+ 0x200000 , /* rb_profile_end */
139
+ };
140
+
141
+ static const seac_screen_layout_t layout_tablet = {
142
+ 0x0A0000 , /* rb_profile_begin */
143
+ 0x200000 , /* rb_profile_end */
144
+ };
145
+
103
146
static dc_status_t
104
147
seac_screen_send (seac_screen_device_t * device , unsigned short cmd , const unsigned char data [], size_t size )
105
148
{
@@ -284,6 +327,8 @@ seac_screen_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t
284
327
285
328
// Set the default values.
286
329
device -> iostream = iostream ;
330
+ device -> cmds = NULL ;
331
+ device -> layout = NULL ;
287
332
memset (device -> info , 0 , sizeof (device -> info ));
288
333
memset (device -> fingerprint , 0 , sizeof (device -> fingerprint ));
289
334
@@ -327,6 +372,15 @@ seac_screen_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t
327
372
328
373
HEXDUMP (context , DC_LOGLEVEL_DEBUG , "Software" , device -> info + SZ_HWINFO , SZ_SWINFO );
329
374
375
+ unsigned int model = array_uint32_le (device -> info + 4 );
376
+ if (model == TABLET ) {
377
+ device -> cmds = & cmds_tablet ;
378
+ device -> layout = & layout_tablet ;
379
+ } else {
380
+ device -> cmds = & cmds_screen ;
381
+ device -> layout = & layout_screen ;
382
+ }
383
+
330
384
* out = (dc_device_t * ) device ;
331
385
332
386
return DC_STATUS_SUCCESS ;
@@ -379,7 +433,8 @@ seac_screen_device_read (dc_device_t *abstract, unsigned int address, unsigned c
379
433
(len ) & 0xFF ,
380
434
};
381
435
unsigned char packet [SZ_READ ] = {0 };
382
- status = seac_screen_transfer (device , CMD_READ , params , sizeof (params ), packet , sizeof (packet ));
436
+ const unsigned int packetsize = device -> cmds -> read == CMD_TABLET_READ ? len : sizeof (packet );
437
+ status = seac_screen_transfer (device , device -> cmds -> read , params , sizeof (params ), packet , packetsize );
383
438
if (status != DC_STATUS_SUCCESS ) {
384
439
ERROR (abstract -> context , "Failed to send the read command." );
385
440
return status ;
@@ -400,11 +455,16 @@ static dc_status_t
400
455
seac_screen_device_dump (dc_device_t * abstract , dc_buffer_t * buffer )
401
456
{
402
457
seac_screen_device_t * device = (seac_screen_device_t * ) abstract ;
458
+ const seac_screen_layout_t * layout = device -> layout ;
403
459
404
460
// Emit a device info event.
405
461
dc_event_devinfo_t devinfo ;
406
462
devinfo .model = array_uint32_le (device -> info + 4 );
407
- devinfo .firmware = array_uint32_le (device -> info + 0x11C );
463
+ if (devinfo .model == TABLET ) {
464
+ devinfo .firmware = array_uint32_le (device -> info + 0x114 );
465
+ } else {
466
+ devinfo .firmware = array_uint32_le (device -> info + 0x11C );
467
+ }
408
468
devinfo .serial = array_uint32_le (device -> info + 0x10 );
409
469
device_event_emit (abstract , DC_EVENT_DEVINFO , & devinfo );
410
470
@@ -415,12 +475,12 @@ seac_screen_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
415
475
device_event_emit (abstract , DC_EVENT_VENDOR , & vendor );
416
476
417
477
// Allocate the required amount of memory.
418
- if (!dc_buffer_resize (buffer , RB_PROFILE_SIZE )) {
478
+ if (!dc_buffer_resize (buffer , layout -> rb_profile_end - layout -> rb_profile_begin )) {
419
479
ERROR (abstract -> context , "Insufficient buffer space available." );
420
480
return DC_STATUS_NOMEMORY ;
421
481
}
422
482
423
- return device_dump_read (abstract , RB_PROFILE_BEGIN , dc_buffer_get_data (buffer ),
483
+ return device_dump_read (abstract , layout -> rb_profile_begin , dc_buffer_get_data (buffer ),
424
484
dc_buffer_get_size (buffer ), SZ_READ );
425
485
}
426
486
@@ -429,16 +489,21 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
429
489
{
430
490
dc_status_t status = DC_STATUS_SUCCESS ;
431
491
seac_screen_device_t * device = (seac_screen_device_t * ) abstract ;
492
+ const seac_screen_layout_t * layout = device -> layout ;
432
493
433
494
// Enable progress notifications.
434
495
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER ;
435
- progress .maximum = RB_PROFILE_SIZE ;
496
+ progress .maximum = layout -> rb_profile_end - layout -> rb_profile_begin ;
436
497
device_event_emit (abstract , DC_EVENT_PROGRESS , & progress );
437
498
438
499
// Emit a device info event.
439
500
dc_event_devinfo_t devinfo ;
440
501
devinfo .model = array_uint32_le (device -> info + 4 );
441
- devinfo .firmware = array_uint32_le (device -> info + 0x11C );
502
+ if (devinfo .model == TABLET ) {
503
+ devinfo .firmware = array_uint32_le (device -> info + 0x114 );
504
+ } else {
505
+ devinfo .firmware = array_uint32_le (device -> info + 0x11C );
506
+ }
442
507
devinfo .serial = array_uint32_le (device -> info + 0x010 );
443
508
device_event_emit (abstract , DC_EVENT_DEVINFO , & devinfo );
444
509
@@ -450,7 +515,7 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
450
515
451
516
// Read the range of the available dive numbers.
452
517
unsigned char range [SZ_RANGE ] = {0 };
453
- status = seac_screen_transfer (device , CMD_RANGE , NULL , 0 , range , sizeof (range ));
518
+ status = seac_screen_transfer (device , device -> cmds -> range , NULL , 0 , range , sizeof (range ));
454
519
if (status != DC_STATUS_SUCCESS ) {
455
520
ERROR (abstract -> context , "Failed to send the range command." );
456
521
goto error_exit ;
@@ -486,7 +551,7 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
486
551
unsigned int count = 0 ;
487
552
unsigned int skip = 0 ;
488
553
unsigned int rb_profile_size = 0 ;
489
- unsigned int remaining = RB_PROFILE_SIZE ;
554
+ unsigned int remaining = layout -> rb_profile_end - layout -> rb_profile_begin ;
490
555
for (unsigned int i = 0 ; i < ndives ; ++ i ) {
491
556
unsigned int number = last - i ;
492
557
@@ -498,15 +563,15 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
498
563
(number ) & 0xFF ,
499
564
};
500
565
unsigned char rsp_address [SZ_ADDRESS ] = {0 };
501
- status = seac_screen_transfer (device , CMD_ADDRESS , cmd_address , sizeof (cmd_address ), rsp_address , sizeof (rsp_address ));
566
+ status = seac_screen_transfer (device , device -> cmds -> address , cmd_address , sizeof (cmd_address ), rsp_address , sizeof (rsp_address ));
502
567
if (status != DC_STATUS_SUCCESS ) {
503
568
ERROR (abstract -> context , "Failed to read the dive address." );
504
569
goto error_free_logbook ;
505
570
}
506
571
507
572
// Get the dive address.
508
573
logbook [i ].address = array_uint32_be (rsp_address );
509
- if (logbook [i ].address < RB_PROFILE_BEGIN || logbook [i ].address >= RB_PROFILE_END ) {
574
+ if (logbook [i ].address < layout -> rb_profile_begin || logbook [i ].address >= layout -> rb_profile_end ) {
510
575
ERROR (abstract -> context , "Invalid ringbuffer pointer (0x%08x)." , logbook [i ].address );
511
576
status = DC_STATUS_DATAFORMAT ;
512
577
goto error_free_logbook ;
@@ -543,11 +608,11 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
543
608
544
609
// Get the end-of-profile pointer.
545
610
if (eop == 0 ) {
546
- eop = previous = RB_PROFILE_INCR (logbook [i ].address , nbytes );
611
+ eop = previous = RB_PROFILE_INCR (logbook [i ].address , nbytes , layout );
547
612
}
548
613
549
614
// Calculate the length.
550
- unsigned int length = RB_PROFILE_DISTANCE (logbook [i ].address , previous );
615
+ unsigned int length = RB_PROFILE_DISTANCE (logbook [i ].address , previous , layout );
551
616
552
617
// Check for the end of the ringbuffer.
553
618
if (length > remaining ) {
@@ -567,7 +632,7 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
567
632
568
633
// Update and emit a progress event.
569
634
progress .maximum -= (ndives - count - skip ) * (SZ_ADDRESS + SZ_HEADER ) +
570
- (RB_PROFILE_SIZE - rb_profile_size );
635
+ (( layout -> rb_profile_end - layout -> rb_profile_begin ) - rb_profile_size );
571
636
device_event_emit (abstract , DC_EVENT_PROGRESS , & progress );
572
637
573
638
// Exit if no dives to download.
@@ -584,7 +649,7 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
584
649
585
650
// Create the ringbuffer stream.
586
651
dc_rbstream_t * rbstream = NULL ;
587
- status = dc_rbstream_new (& rbstream , abstract , SZ_READ , SZ_READ , RB_PROFILE_BEGIN , RB_PROFILE_END , eop , DC_RBSTREAM_BACKWARD );
652
+ status = dc_rbstream_new (& rbstream , abstract , SZ_READ , SZ_READ , layout -> rb_profile_begin , layout -> rb_profile_end , eop , DC_RBSTREAM_BACKWARD );
588
653
if (status != DC_STATUS_SUCCESS ) {
589
654
ERROR (abstract -> context , "Failed to create the ringbuffer stream." );
590
655
goto error_free_profile ;
@@ -594,7 +659,7 @@ seac_screen_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
594
659
unsigned int offset = rb_profile_size ;
595
660
for (unsigned int i = 0 ; i < count ; ++ i ) {
596
661
// Calculate the length.
597
- unsigned int length = RB_PROFILE_DISTANCE (logbook [i ].address , previous );
662
+ unsigned int length = RB_PROFILE_DISTANCE (logbook [i ].address , previous , layout );
598
663
599
664
// Move to the start of the current dive.
600
665
offset -= length ;
0 commit comments