diff --git a/Notes b/Notes index 1dcc8c4..5bc2502 100644 --- a/Notes +++ b/Notes @@ -1 +1,42 @@ Command d-249 Settings + +Send 0x00 0xFF + + Edit a 0xFF 0x59 + + +Read info + get 00 fa 01 00 00 00 6C string + +Read is_ready + get 00 fa 01 00 00 00 6c string + +Get Image return header + 00 fc 01 00 00 1d 73 5a 2d 08 ff ff ff ff || 89 [ 50 4E 47 ] (PNG) + P N G + +PNG Magic number 89 50 4e 47 0d 0a 1a 0a + +Header format + + 00 + + Type + + Num Packets + + 00 00 00 6c String Marker + + +Set GetInfo, IsReady + + +NOTE Program data comes across in ASCII :) + +First header with serial number is repeated + +tokens calc.hpvars + calc.hpsettings + list off all apps comes through in Ascii with & as Start + + diff --git a/QtHPConnect.pro b/QtHPConnect.pro index bb668d0..110af25 100644 --- a/QtHPConnect.pro +++ b/QtHPConnect.pro @@ -139,7 +139,8 @@ DISTFILES += \ CHANGELOG.md \ NEWS \ AUTHORS \ - Notes + Notes \ + TODO.md ../hplp-master/libhpcalcs/tests/test_hpcalcs.c unix|win32: LIBS += -lhidapi-libusb diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..6583255 --- /dev/null +++ b/TODO.md @@ -0,0 +1,8 @@ +17/02/2019 +1 GUI + About + Load and read program files + Load Screen shot and display +2 Comms + Understand what the calc is doing! +3 Backup to disk diff --git a/errorhandler.h b/errorhandler.h index ded6c59..6fb9a75 100644 --- a/errorhandler.h +++ b/errorhandler.h @@ -18,6 +18,24 @@ enum ErrLevel { L7 //information }; +typedef enum { + + ERR_SUCCESS = 0, // Must be equal to ERR_HPLIBS_GENERIC_FIRST + ERR_MALLOC, + ERR_INVALID_HANDLE, + ERR_INVALID_PARAMETER, + ERR_INVALID_MODEL, + ERR_LIBRARY_INIT, + ERR_LIBRARY_EXIT, + ERR_LIBRARY_CONFIG_VERSION, + + ERR_FILE_FIRST, + ERR_FILE_FILENAME, + ERR_FILE_LAST + +} hp_error; + + class errorHandler { private: QObject * pParent; diff --git a/getnumber.ui b/getnumber.ui index 6496010..1dd93a8 100644 --- a/getnumber.ui +++ b/getnumber.ui @@ -6,7 +6,7 @@ 0 0 - 347 + 427 118 @@ -18,7 +18,7 @@ 0 70 - 321 + 411 32 @@ -32,9 +32,9 @@ - 60 + 30 20 - 261 + 381 32 diff --git a/hpdata.cpp b/hpdata.cpp index 6462b30..5efc28c 100644 --- a/hpdata.cpp +++ b/hpdata.cpp @@ -43,6 +43,7 @@ hpCalcData::hpCalcData(hpusb * handle) if (hp_api) { hp_api->hp_open(getHandle()); } + } //return the interface class @@ -100,6 +101,61 @@ void hpCalcData::readSettings() { emit dataChanged(change); } +//read Settings via usb +void hpCalcData::readScreen() { + + hpusb * api; + hp_Handle * handle; + hp_Settings hpset; + + log("Reading Screen"); + qDebug()<<"Reading Screen"; + api=getAPI(); + handle=getHandle(); + + QByteArray imageData; + + if (api) { + if(handle) { + qDebug()<usbhandle); + if (api) { + api->get_screen_shot(handle,&imageData); + if (screenShot!=nullptr) { + delete screenShot; + } + qDebug()<<"New ScreenShot"; + screenShot = new QPixmap(); + + qDebug()<<"Loading data"; + qDebug()<loadFromData(imageData); + } + } + } + + emit emitChange(HP_SCREEN); +} + +void hpCalcData::emitChange(DataType type) { + + hp_Change change; + change.dataChange=type; + change.calc = this; + + emit dataChanged(change); + +} + +hp_ScreenShot hpCalcData::getScreenShot() { + hp_ScreenShot scn; + + scn.image = screenShot; + scn.format = CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x16; + scn.calc = this; + + return scn; +} + //set Settings int hpCalcData::setSettings(hp_Settings set) { @@ -130,9 +186,7 @@ void hpCalcData::readInfo() { } hp_info=hpinfo; - hp_Change change; - change.dataChange=HP_MAIN; - emit dataChanged(change); + emit emitChange(HP_MAIN); } void hpCalcData::vpkt_send_experiments(int cmd) { @@ -145,8 +199,12 @@ void hpCalcData::vpkt_send_experiments(int cmd) { if (api) { if(handle) { - if (api) - api->vpkt_send_experiments(handle,cmd); + if (api) { + api->is_ready(handle); + + //api->vpkt_send_experiments(handle,cmd); + + } } } diff --git a/hpdata.h b/hpdata.h index 19d767a..922f684 100644 --- a/hpdata.h +++ b/hpdata.h @@ -15,7 +15,8 @@ enum DataType { HP_NOTE=6, HP_PROG=7, HP_REAL=8, - HP_VAR=9 + HP_VAR=9, + HP_SCREEN=10 }; struct hp_Information { @@ -47,8 +48,17 @@ struct hpDataStruct { }; +class hpCalcData; + +struct hp_ScreenShot { + QPixmap * image; + hp_screenshot_format format; + hpCalcData * calc; +}; + struct hp_Change { DataType dataChange=HP_MAIN; + hpCalcData * calc; }; class hpCalcData: public QObject @@ -58,6 +68,7 @@ class hpCalcData: public QObject private: const static QString func_list[][2]; const static DataType func_type[]; + QPixmap * screenShot=nullptr; DataType type; hpusb * hp_api; hp_Handle hp_handle; @@ -72,11 +83,14 @@ public: void setInfo(hp_Information); void readInfo(); void readSettings(); + void readScreen(); + hp_ScreenShot getScreenShot(); hp_Information getInfo(); QString getName(); hp_Settings getSettings(); int setSettings(hp_Settings set); void vpkt_send_experiments(int ); + void emitChange(DataType type); //public slots: diff --git a/hptreeitem.cpp b/hptreeitem.cpp index 79c11d9..d0b0e31 100644 --- a/hptreeitem.cpp +++ b/hptreeitem.cpp @@ -242,6 +242,7 @@ QString hpTreeItem::getName() { return func_list[dt2int()][0]; } +//Slot to respond to data changes void hpTreeItem::dataChange(hp_Change hpchange) { hpCalcData * ptr=nullptr; @@ -254,5 +255,10 @@ void hpTreeItem::dataChange(hp_Change hpchange) { setData(name,Qt::DisplayRole); } break; + case HP_SCREEN: { + qDebug()<<"Screen Shot Changed"; + emit dataChanged(hpchange); + } + break; } } diff --git a/hptreeitem.h b/hptreeitem.h index ea2d7b1..dff417b 100644 --- a/hptreeitem.h +++ b/hptreeitem.h @@ -48,6 +48,9 @@ private: hp_mdiTextEdit * hptextedit = nullptr; int dt2int(); +signals: + void dataChanged(hp_Change datachange); + }; Q_DECLARE_METATYPE(hpTreeItem *) diff --git a/hpusb.cpp b/hpusb.cpp index 2a9a2d4..6f6ad83 100644 --- a/hpusb.cpp +++ b/hpusb.cpp @@ -4,21 +4,20 @@ // // Note hpusb opens an interface but can have multiple usb ports // open. Hence handle information is stored else where +// +// Norm: +// return 0 = success +// return <> 0 = error +#include - +#include "global.h" #include "hpusb.h" #include "hpdata.h" #include #include -#include "global.h" -#include - -//return 0 = success -//return > err - - +//Constructor hpusb::hpusb() { lb_init=0; @@ -135,7 +134,8 @@ int hpusb::hp_open(hp_Handle * handle) { return ret; } -//replace with libusb_open_device_with_vid_pid +// check device handler for idVendor and idProduct +// replace with libusb_open_device_with_vid_pid int hpusb::is_device(libusb_device * device) { libusb_device_descriptor desc = {0}; @@ -154,6 +154,7 @@ int hpusb::is_device(libusb_device * device) { return 0; } +//print the device descriptor void hpusb::dumpDevice(libusb_device * device) { QString dump("Device Descriptor\n"); @@ -180,32 +181,205 @@ void hpusb::dumpDevice(libusb_device * device) { qDebug()<usbhandle; - qDebug()<usbhandle); - - int ret; + int ret=-1; int trans=0; - if (!devh) - return -1; - //write - log("Send.."); - ret = libusb_interrupt_transfer(devh, 0x02, pktin->buffer, pktin->size, + if (handle != NULL && pktout != NULL) { + + prime_raw_hid_pkt raw; + uint32_t i, q, r; + uint32_t offset = 0; + uint8_t pkt_id = 0; + libusb_device_handle * devh = handle->usbhandle; + if (devh!=nullptr) { + memset((void *)&raw, 0, sizeof(raw)); + q = (pktout->size) / (PRIME_RAW_DATA_SIZE); + r = (pktout->size) % (PRIME_RAW_DATA_SIZE); + + qDebug()<1) { + raw.data[0]= 0x01; + raw.data[1] = pkt_id; + memcpy(raw.data + 2, pktout->data + offset, PRIME_RAW_DATA_SIZE-1); + offset += PRIME_RAW_DATA_SIZE - 1; + } + else { + memcpy(raw.data, pktout->data + offset, PRIME_RAW_DATA_SIZE-1); + offset += PRIME_RAW_DATA_SIZE - 1; + } + + log("In sync send transfer"); + qDebug()<usbhandle); + + //write + log("Send.."); + ret = libusb_interrupt_transfer(devh, ENDPOINT_OUT, raw.data, raw.size, + &trans,10000); + if (ret) { + log(QString().sprintf("Write Error: %s\n", libusb_error_name(ret))); + r = 0; + break; + } + else { + log(QString().sprintf("Write bytes: %d\n", trans)); + } + // Increment packet ID, which seems to be necessary for computer -> calc packets + pkt_id++; + if (pkt_id == 0xFF) { + pkt_id = 0; // Skip 0xFF, which is used for other purposes. + } + } + + if (r || !pktout->size) { + if (i>1) { + raw.size = r + 2; + raw.data[0] = 0x01; + raw.data[1] = pkt_id; + memcpy(raw.data + 2, pktout->data + offset, PRIME_RAW_DATA_SIZE-1); + } + else + { + raw.size = r; + memcpy(raw.data, pktout->data + offset, PRIME_RAW_DATA_SIZE-1); + } + log("Send small packet.."); + + ret = libusb_interrupt_transfer(devh, ENDPOINT_OUT, raw.data, raw.size, &trans,10000); - log(QString().sprintf("Write Error: %s\n", libusb_error_name(ret))); - log(QString().sprintf("Write bytes: %d\n", trans)); + if (ret) { + log(QString().sprintf("Write Error: %s\n", libusb_error_name(ret))); + } + else { + log(QString().sprintf("Write bytes: %d\n", trans)); + } + } - //read - log("Recieve..."); - ret = libusb_interrupt_transfer(devh,0x81,pktout->buffer,pktout->size-8,&trans,10000); + } + } + return ret; +} + +//extracts the header from the pkt and returns it in the header structure +int hpusb::extract_header(hp_pkt_in * pktin, int start, usb_header * uh) { + + int b_0; + int b_1; + int b_2; + int b_3; + int b_4; + int b_5; + int b_6; + int b_7; + + b_0=pktin->data[0]; + b_1=pktin->data[1]; + b_2=pktin->data[2]; + b_3=pktin->data[3]; + b_4=pktin->data[4]; + b_5=pktin->data[5]; + b_6=pktin->data[6]; + b_7=pktin->data[7]; + + + qDebug()<data[start]; + + if(b_0==0x01) { + uh->type=HP_HDR_CHUNK; + uh->typecode=0; + uh->chunk=pktin->data[start+1]; + QString msg = QString("Chunk %1").arg(uh->chunk); + msg += QString("\n 00 %0x1").arg(pktin->data[0]); + msg += QString("\n 01 %0x1").arg(pktin->data[1]); + msg += QString("\n 02 %0x1").arg(pktin->data[2]); + qDebug()<type=HP_HDR_STD; + uh->cmd=b_1; + uh->items=0; + uh->chunk=0; + uh->size=1024; + } + else + { + + uh->typecode=pktin->data[start+4]; + if(uh->typecode==0XF7) + { + uh->type=HP_HDR_FIRST; + uh->items=pktin->data[start+5]; + QString msg = QString("Size: %1").arg(pktin->data[start+4]); + qDebug()<size=(uint32_t)(pktin->data[start+5]); + uh->chunk=0; + msg = QString("First Header item: %1 size: %2").arg(uh->items).arg(uh->size); + qDebug()<usbhandle; + + qDebug()<usbhandle); + + if (!devh) + return -1; + + ret = libusb_interrupt_transfer(devh,ENDPOINT_IN,pktin->data,1024,&trans,5000); + + extract_header(pktin,0,&uh1); + + qDebug()<0x00)) { + qDebug()<data[trans],1024,&trans_c,5000); + extract_header(pktin,trans, &uh2); + qDebug()< dump(pktout->buffer,trans); + main_err-> dump(pktin->data,trans); } return ret; } +//request to recieve a file transfer +int sync_s_recv_file(hp_Handle *) { + + return 0; +} + +//recieve the file transfer +int sync_r_recv_file(hp_Handle *) { + + return 0; +} + +//Get a screen shot. HP replies with image starting on byte 14 +//ToDo - make robust +int hpusb::get_screen_shot(hp_Handle * handle, QByteArray * imageData) { + + int res; + if (handle != NULL) { + + uint8_t transferbuffer[LEN_IN_BUFFER*8 ]; + uint8_t in_buffer[LEN_IN_BUFFER+8]; + hp_pkt_in pktin; + hp_pkt_out pktout; + + transferbuffer[0]=0x00; + transferbuffer[1]=CMD_PRIME_RECV_SCREEN; + transferbuffer[2]=(uint8_t) CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x16; + + pktout.cmd = CMD_PRIME_RECV_SCREEN; + pktout.data = transferbuffer; + pktout.size=1024; + + if (!(res=submit_sync_s_transfer(handle,&pktout))){ + + pktin.cmd= CMD_PRIME_RECV_SCREEN; + pktin.data=in_buffer; + pktin.size=1024*8; + log(QString("%1: Waiting for a reply").arg(__FUNCTION__)); + + if (!submit_sync_r_transfer(handle,&pktin)){ + log(QString("%1: Recieved a reply").arg(__FUNCTION__)); + //Trying to understand reply + + QByteArray rd= QByteArray(reinterpret_cast(pktin.data), pktin.size); + *imageData = QByteArray(reinterpret_cast(&pktin.data[14]), pktin.size-14); + + log(QString().sprintf("%d bytes received",pktin.size)); + main_err-> dump(pktin.data,pktin.size); + // lookfordouble(rd,64); + } + } + + } + + qDebug()<>8)&0xFF); +// transferbuffer[1]=((cmd>>0)&0xFF); + + transferbuffer[0]=0x00; + transferbuffer[1]=CMD_PRIME_CHECK_READY; + + pktout.cmd = CMD_PRIME_CHECK_READY; + pktout.data = transferbuffer; + pktout.size=2; + + if (!(res=submit_sync_s_transfer(handle,&pktout))){ + + pktin.cmd= CMD_PRIME_CHECK_READY; + pktin.data=in_buffer; + pktin.size=1024; + log(QString("%1: Waiting for a reply").arg(__FUNCTION__)); + + if (!submit_sync_r_transfer(handle,&pktin)){ + log(QString("%1: Recieved a reply").arg(__FUNCTION__)); + //Trying to understand reply + QByteArray rd= QByteArray(reinterpret_cast(pktin.data), pktin.size); + // lookfordouble(rd,64); + } + } + else { + log(QString("%1: Could not send ready request ").arg(__FUNCTION__)); + return res; + } + } + return res; + } + +int hpusb::load_info(hp_Handle * handle, hp_Information * hpinfo) { + + uint8_t transferbuffer[LEN_IN_BUFFER+8]; + uint8_t in_buffer[LEN_IN_BUFFER+8]; + + hp_pkt_in pktin; + hp_pkt_out pktout; + + memset((void *)&transferbuffer, 0, sizeof(transferbuffer)); + + qDebug()<(pktin.data), pktin.size); + + //find name + ind=rd.indexOf(QChar(0x6c),0)+1; + QByteArray str1 =rd.mid(ind,64); + + QString name; + name = codec->toUnicode(str1); + hpinfo->name=name; + + //find OS Version + unsigned char searchstr[] = {0x80,0x20,0x80,0x01,0x62,0x01}; + ind+=rd.indexOf((char *) searchstr,ind+64)+4; + qDebug()<toUnicode(str1); + hpinfo->osver=osv; + qDebug()<toUnicode(str1); + hpinfo->serialnum=serial; + log(serial); + + //find Application Version + ind+=16; + str1 =rd.mid(ind,16); + +// QByteArray db= QByteArray(reinterpret_cast(&pktout.buffer[ind]), pktout.size-ind); + + return 0; + } + else { + log("failed to read info from device"); + return 1; + } + } + return 0; +} + +int hpusb::lookfordouble (QByteArray rd, int start) { + long double num=0; + QString app; + QByteArray str1; + QTextCodec * codec = QTextCodec::codecForName("UTF-8"); + app = codec->toUnicode(str1); + log(app); + + int i,ind; + ind=start; + + for (i=0; i<300; i++) { + ind+=1; + str1 =rd.mid(ind,sizeof(num)); + num= *(long double*)(str1.constData()); + app = codec->toUnicode(str1); + // qDebug()<>8)&0xFF); + transferbuffer[1]=((cmd>>0)&0xFF); + +/* transferbuffer[0]=0xFF; + transferbuffer[1]=0xEC; + transferbuffer[2]=0x00; + transferbuffer[3]=0x00; + transferbuffer[4]=0x00; + transferbuffer[5]=0x00; + transferbuffer[6]=0x00; + transferbuffer[7]=0x00; + transferbuffer[8]=0x00; + transferbuffer[9]=0x00; + transferbuffer[10]=0x00; +*/ + //CRC + quint16 crcBytes = qChecksum((char *)&transferbuffer[2],9); + + qDebug()<>8)&0xFF; + transferbuffer[12]=(crcBytes>>0)&0xFF; + + transferbuffer[11]=0x1c; + transferbuffer[12]=0xf5; + + transferbuffer[13]=0x97; + transferbuffer[14]=0x01; + transferbuffer[15]=0x33; + transferbuffer[16]=0x45; + transferbuffer[17]=0xe6; + transferbuffer[18]=0x76; + transferbuffer[19]=0x00; + transferbuffer[20]=0x00; + transferbuffer[21]=0x00; + transferbuffer[22]=0x00; + transferbuffer[23]=0x48; + + + transferbuffer[1024]=0x00; + transferbuffer[1025]=0x00; + transferbuffer[1026]=0x07; + transferbuffer[1027]=0x00; + transferbuffer[1028]=0x00; + transferbuffer[1029]=0x00; + transferbuffer[1030]=0xfd; + transferbuffer[1031]=0x01; + +/* + transferbuffer[0]=0x01; + transferbuffer[1]=0x01; + + transferbuffer[2]=0x00; + transferbuffer[3]=0x00; + transferbuffer[4]=0x07; + transferbuffer[5]=0x00; + transferbuffer[6]=0x00; + transferbuffer[7]=0x00; + transferbuffer[8]=0xfd; + transferbuffer[9]=0x01; +*/ + + + + pktout.data=transferbuffer; + pktout.size=1024; + + pktin.data=in_buffer; + pktin.size=sizeof(in_buffer); +// pktout.size=PRIME_RAW_HID_DATA_SIZE+16; + + submit_sync_s_transfer(handle,&pktout); + + submit_sync_r_transfer(handle,&pktin); + { + + transferbuffer[0]=0x01; + transferbuffer[1]=0x01; + transferbuffer[2]=0x00; + transferbuffer[3]=0x00; + transferbuffer[4]=0x00; + transferbuffer[5]=0x07; + transferbuffer[6]=0x00; + transferbuffer[7]=0x00; + transferbuffer[8]=0x00; + transferbuffer[9]=0x00; + + pktout.data=transferbuffer; + pktout.size=1024*2; + + // submit_sync_s_transfer(handle,&pktout); + // submit_sync_r_transfer(handle,&pktin); + + return 0; + } + + return 1; +} + +int hpusb::hp_close(hp_Handle * handle) +{ + if (handle) { + if (handle->dev_open) { + libusb_release_interface(handle->usbhandle, 0); + libusb_close(handle->usbhandle); + handle->dev_open =0; + } + } + return 0; +} + + +// debugging function to display libusb_transfer +void hpusb::print_libusb_transfer(struct libusb_transfer *p_t) +{ int i; + if ( NULL == p_t){ + log("No libusb_transfer...\n"); + } + else { + log("libusb_transfer structure:\n"); + log(QString().sprintf("flags =%x \n", p_t->flags)); + log(QString().sprintf("endpoint=%x \n", p_t->endpoint)); + log(QString().sprintf("type =%x \n", p_t->type)); + log(QString().sprintf("timeout =%d \n", p_t->timeout)); + // length, and buffer are commands sent to the device + log(QString().sprintf("length =%d \n", p_t->length)); + log(QString().sprintf("actual_length =%d \n", p_t->actual_length)); + log(QString().sprintf("buffer =%p \n", p_t->buffer)); + + for (i=0; i < p_t->length; i++){ + log(QString().sprintf(" %x", i, p_t->buffer[i])); + } + } + return; +} + + //send a submission int hpusb::submit_async_transfer(hp_Handle * handle, hp_pkt_in * pktin, hp_pkt_out *pktout) { @@ -245,7 +835,7 @@ int hpusb::submit_async_transfer(hp_Handle * handle, hp_pkt_in * pktin, hp_pkt_o //Filling //libusb_fill_interrupt_setup(in_buffer,LIBUSB_RECIPIENT_DEVICE ,LIBUSB_REQUEST_TYPE_STANDARD,0,0,16); libusb_fill_control_transfer( transfer_in, devh, - pktin->buffer, // Note: in_buffer is where input data written. + pktin->data, // Note: in_buffer is where input data written. cb_in, nullptr, 1000); // no user data //take the initial time measurement @@ -395,208 +985,6 @@ void cb_in(struct libusb_transfer *transfer) } } -int hpusb::hp_func() { - return 0; -} - -int hpusb::is_ready() { - - return 0; -} - -int hpusb::load_info(hp_Handle * handle, hp_Information * hpinfo) { - - uint8_t transferbuffer[PRIME_RAW_HID_DATA_SIZE ]; - uint8_t out_buffer[LEN_IN_BUFFER+8]; - - hp_pkt_in pktin; - hp_pkt_out pktout; - - transferbuffer[0]=0x0; - transferbuffer[1]=CMD_PRIME_GET_INFOS; - - pktin.buffer=transferbuffer; - pktin.size=2; - - pktout.buffer=out_buffer; - pktout.size=sizeof(out_buffer); -// pktout.size=PRIME_RAW_HID_DATA_SIZE+16; - - if (!submit_sync_transfer(handle,&pktin,&pktout)){ - //unpack data - log("unpacking data"); - - int ind=0; - QTextCodec * codec = QTextCodec::codecForName("UTF-8"); - QByteArray rd= QByteArray(reinterpret_cast(pktout.buffer), pktout.size); - - //find name - ind=rd.indexOf(QChar(0x6c),0)+1; - QByteArray str1 =rd.mid(ind,64); - - QString name; - name = codec->toUnicode(str1); - hpinfo->name=name; - - //find OS Version - unsigned char searchstr[] = {0x80,0x20,0x80,0x01,0x62,0x01}; - ind+=rd.indexOf((char *) searchstr,ind+64)+4; - qDebug()<toUnicode(str1); - hpinfo->osver=osv; - qDebug()<toUnicode(str1); - hpinfo->serialnum=serial; - log(serial); - - //find Application Version - ind+=16; - str1 =rd.mid(ind,16); - QString app; - app = codec->toUnicode(str1); - //hpinfo->appver=app; - log(app); - -// QByteArray db= QByteArray(reinterpret_cast(&pktout.buffer[ind]), pktout.size-ind); - - long double num=0; - int i; - ind+=16; - for (i=0; i<300; i++) { - ind+=1; - str1 =rd.mid(ind,sizeof(num)); - num= *(long double*)(str1.constData()); - app = codec->toUnicode(str1); - // qDebug()<dev_open) { - libusb_release_interface(handle->usbhandle, 0); - libusb_close(handle->usbhandle); - handle->dev_open =0; - } - } - return 0; -} - - -// debugging function to display libusb_transfer -void hpusb::print_libusb_transfer(struct libusb_transfer *p_t) -{ int i; - if ( NULL == p_t){ - log("No libusb_transfer...\n"); - } - else { - log("libusb_transfer structure:\n"); - log(QString().sprintf("flags =%x \n", p_t->flags)); - log(QString().sprintf("endpoint=%x \n", p_t->endpoint)); - log(QString().sprintf("type =%x \n", p_t->type)); - log(QString().sprintf("timeout =%d \n", p_t->timeout)); - // length, and buffer are commands sent to the device - log(QString().sprintf("length =%d \n", p_t->length)); - log(QString().sprintf("actual_length =%d \n", p_t->actual_length)); - log(QString().sprintf("buffer =%p \n", p_t->buffer)); - - for (i=0; i < p_t->length; i++){ - log(QString().sprintf(" %x", i, p_t->buffer[i])); - } - } - return; -} - hpusb::~hpusb() { libusb_exit(ctx); } diff --git a/hpusb.h b/hpusb.h index bdca005..cb97999 100644 --- a/hpusb.h +++ b/hpusb.h @@ -2,6 +2,7 @@ #define HPUSB_H #include +#include struct hp_Settings; @@ -15,9 +16,10 @@ struct hp_Settings; #define USB_PID_PRIME3 (0x2441) //! Size of a raw HID packet for the Prime. #define PRIME_RAW_HID_DATA_SIZE (64) +#define PRIME_RAW_DATA_SIZE (1024) -#define LEN_IN_BUFFER 1024 -//*8 + +#define LEN_IN_BUFFER 1024*8 #define USB_ENDPOINT_IN (LIBUSB_ENDPOINT_IN | 1) /* endpoint address */ #define USB_ENDPOINT_OUT (LIBUSB_ENDPOINT_OUT | 2) /* endpoint address */ @@ -33,26 +35,79 @@ struct hp_Settings; #define CMD_PRIME_SEND_KEY (0xEC) #define CMD_PRIME_SET_DATE_TIME (0xE7) +#define ENDPOINT_OUT (0x02) +#define ENDPOINT_IN (0x81) +#define HEADER_LEN (0xFD) + struct hp_Handle { libusb_device_handle *usbhandle = nullptr; libusb_device *usbdevice = nullptr; int dev_open=0; }; +struct usb_firstchunk { + uint8_t start1; + uint8_t start2; + uint8_t type; + uint8_t items; + int size; +}; + +struct usb_chunk { + uint8_t start1; + uint8_t chunk; //the chunk number +}; + +enum usb_header_type { + HP_HDR_FIRST, + HP_HDR_CHUNK, + HP_HDR_STD + +}; + +struct usb_header { + usb_header_type type; + uint8_t cmd; + uint8_t typecode; + uint8_t items; + int chunk; + int name_length; + uint32_t size; +}; + struct hp_cmd { }; struct hp_pkt_in { - uint8_t * buffer; - int size; + uint8_t * data; + uint32_t size; + uint8_t cmd; }; struct hp_pkt_out { - uint8_t * buffer; - int size; + uint8_t * data; + uint32_t size; + uint8_t cmd; }; +typedef enum { + // 5 is triggered periodically by the official connectivity kit. It returns something with a PNG header, but much smaller. + CALC_SCREENSHOT_FORMAT_FIRST = 8, + CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x16 = 8, + CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x4 = 9, + CALC_SCREENSHOT_FORMAT_PRIME_PNG_160x120x16 = 10, + CALC_SCREENSHOT_FORMAT_PRIME_PNG_160x120x4 = 11, + CALC_SCREENSHOT_FORMAT_LAST ///< Keep this one last +} hp_screenshot_format; + +//! Structure defining a raw packet for the Prime, used at the lowest layer of the protocol implementation. +typedef struct +{ + uint32_t size; + uint8_t data[PRIME_RAW_DATA_SIZE + 1]; +} prime_raw_hid_pkt; + struct hp_Information; void cb_out(struct libusb_transfer *transfer); @@ -99,15 +154,21 @@ class hpusb void dumpDevice(libusb_device * ); int hp_open(hp_Handle *); int submit_async_transfer(hp_Handle *, hp_pkt_in *, hp_pkt_out *); - int submit_sync_transfer(hp_Handle *, hp_pkt_in *, hp_pkt_out *); + int submit_sync_s_transfer(hp_Handle *, hp_pkt_out *); + int submit_sync_r_transfer(hp_Handle *, hp_pkt_in *); + int sync_s_recv_file(hp_Handle *); + int sync_r_recv_file(hp_Handle *); + int extract_header(hp_pkt_in *, int, usb_header *); int submit_callback(); int hp_close(hp_Handle * ); int hp_func(); - int is_ready(); + int is_ready(hp_Handle *); int load_info(hp_Handle *, hp_Information *); + int lookfordouble (QByteArray , int ); int get_info( /*calc_infos * infos*/); int get_settings(hp_Handle * , hp_Settings * ); int set_settings(hp_Handle * , hp_Settings set); + int get_screen_shot(hp_Handle *, QByteArray *); int vpkt_send_experiments(hp_Handle * handle, int cmd); // Function Prototypes: diff --git a/mainwindow.cpp b/mainwindow.cpp index fd5e1e6..52c0df6 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -60,8 +61,8 @@ MainWindow::MainWindow(QWidget *parent) : main_err = new errorHandler(this); //data models - myModel= new dataModel(0); - hpTreeModel = new treeModel(0); + myModel= new dataModel(this); + hpTreeModel = new treeModel(this); qDebug()<<"1"; @@ -93,6 +94,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->actionLog,SIGNAL(triggered()),this,SLOT(createLogWindow())); connect(ui->actionTest,SIGNAL(triggered()),this,SLOT(testFunction())); connect(ui->actionTestSettings,SIGNAL(triggered()),this,SLOT(onTestSettings())); + connect(ui->actionTestScreen,SIGNAL(triggered()),this,SLOT(onTestScreen())); connect(ui->tvCalculators, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(on_tvCalculators_customContextMenuRequested(const QPoint &))); //default data @@ -117,7 +119,7 @@ void MainWindow::testFunction() { pH=getTreeModel()->getCalculator("IAN"); if (pH) { - cmd = QInputDialog::getInt(this,"Get Command","CMD:",0,0,256); + cmd = QInputDialog::getInt(this,"Get Command","CMD:",0,0,0xFFFF); log("command is "+QString().sprintf("%x",cmd)); pH->vpkt_send_experiments(cmd); } @@ -184,6 +186,19 @@ void MainWindow::onTestSettings() hpdata->readSettings(); } +void MainWindow::onTestScreen() +{ + qDebug()<<"MainWindow::in test Screen"; + + QString key; + key=hpTreeModel->getLastDataKey(); + hpCalcData * hpdata; + qDebug()<<"MainWindow:: getKey"; + + hpdata=hpTreeModel->getHpCalcData(key); + if(hpdata) + hpdata->readScreen(); +} //Experimental void MainWindow::loadTextFile() @@ -351,6 +366,61 @@ void MainWindow::showMonitor() { } } +// slot to process low level changes that affect the main Window +void MainWindow::dataChange(hp_Change hpchange) { + + hpCalcData * ptr=nullptr; + qDebug()<<"MainWindow Datachange"; + switch (hpchange.dataChange) { + case HP_MAIN: + + break; + case HP_SCREEN: { + qDebug()<<"Reciebed screenshot changed"; + if (hpchange.calc!=nullptr) { + hp_ScreenShot scrn; + scrn = hpchange.calc->getScreenShot(); + monitorAddImage(scrn); + } + } + break; + } +} + +//Add screen shots to the message window +void MainWindow::monitorAddImage(hp_ScreenShot scrnshot) { + + qDebug()<<"In Monitor Add Screen Shot"; + QPixmap * pic; + int col; + int row; + int count; + + if (scrnshot.image!=nullptr) { + + //Todo fix default image + pic=new QPixmap(":/icons/add_background_32x32.png"); + QLabel * label = new QLabel("Screenshot"); + label->setPixmap(*pic); + row = ui->wMonitorGrid->rowCount(); + col = ui->wMonitorGrid->columnCount(); + count = ui->wMonitorGrid->count(); + + col=count%3; + row=count/3; + + qDebug()<<"Row set"<wMonitorGrid->addWidget(label,row,col,Qt::AlignTop); + } + else + { + log("Could not load image"); + } + ui->dwMonitor->show(); + +} + void MainWindow::exit() { delete treeMenu; close(); diff --git a/mainwindow.h b/mainwindow.h index 993329b..892c262 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -40,12 +40,14 @@ public: private slots: void onOpen(); void onTestSettings(); + void onTestScreen(); void selectionChangedSlot(const QItemSelection & /*newSelection*/, const QItemSelection & /*oldSelection*/); void about(); void showContent(); void showCalculator(); void showMessage(); void showMonitor(); + void dataChange(hp_Change); void clickedCalculator(QModelIndex); void exit(); void createLogWindow(); @@ -69,6 +71,9 @@ private: void loadTextFile(); void createTextWindow(); QMdiArea * getMdi(); + void monitorAddImage(hp_ScreenShot scrnshot); + + }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 93f4593..8b663df 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -186,6 +186,7 @@ + @@ -278,7 +279,7 @@ - + @@ -490,6 +491,18 @@ TestSettings + + + + :/icons/add_background_32x32.png:/icons/add_background_32x32.png + + + TestScreen + + + Test get Screen Function + + diff --git a/treemodel.cpp b/treemodel.cpp index 03eaea0..a28cff9 100644 --- a/treemodel.cpp +++ b/treemodel.cpp @@ -6,6 +6,7 @@ treeModel::treeModel(QObject *parent) { setItemPrototype(new hpTreeItem()); createRoot(); + setParent(parent); } int treeModel::createRoot() @@ -25,6 +26,8 @@ int treeModel::addCalculator(QString name, hpusb * handle){ hpCalc->setIcon(QIcon(":/icons/monitor_32x32.png")); hpCalc->setToolTip(QString("Calculator contents")); QObject::connect(hpData, SIGNAL(dataChanged(hp_Change)),hpCalc, SLOT(dataChange(hp_Change))); + if (parent()!=nullptr) + QObject::connect(hpData, SIGNAL(dataChanged(hp_Change)),parent(), SLOT(dataChange(hp_Change))); setHpCalcData(name,hpData,hpCalc); rootNode->appendRow(hpCalc); hpData->readInfo();