Changeset 1155
- Timestamp:
- 04/24/11 21:21:02 (2 years ago)
- Location:
- trunk/core
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/core/luascript.c
r1101 r1155 61 61 data = (char *)lua_tolstring(L,index,&datasize); 62 62 break; 63 // TODO this converts to a string and returns as STRING, format as described at 63 // TODO this uses usb_msg_table_to_string to serialize the table 64 // the default format is described in 64 65 // http://chdk.setepontos.com/index.php?topic=4338.msg62606#msg62606 65 // for compatibility with current PTPCAM/PTPCAMGUI implementation66 // later we should switch to a proper serialized table with it's own return type67 case LUA_TTABLE:68 lua_script_disable_yield_hook(); // don't want to y eild while converting66 // other formats can be implemented by overriding this function in your lua code 67 case LUA_TTABLE: { 68 int result; 69 lua_script_disable_yield_hook(); // don't want to yield while converting 69 70 lua_getglobal(L, "usb_msg_table_to_string"); // push function 70 71 lua_pushvalue(L, index); // copy specified index to top of stack 71 lua_pcall(L,1,1,0); // this will leave an error message as a string on the stack if call fails72 result = lua_pcall(L,1,1,0); // this will leave an error message as a string on the stack if call fails 72 73 lua_script_enable_yield_hook(); 73 // an empty table will be returned as an empty string 74 if( result ) { 75 // if called from lua, throw a normal error 76 if( msgtype == PTP_CHDK_S_MSGTYPE_USER ) { 77 luaL_error(L,lua_tostring(L,-1)); 78 return NULL; // not reached 79 } else { // if it's a return, convert the message to an ERR 80 msgtype = PTP_CHDK_S_MSGTYPE_ERR; 81 datatype = PTP_CHDK_S_ERRTYPE_RUN; 82 data = (char *)lua_tolstring(L,-1,&datasize); 83 break; 84 } 85 } 86 // an empty table is returned as an empty string by default 74 87 // a non-string should never show up here 75 if ( ! (lua_isstring(L,-1) /*&& ( lua_objlen(L,-1) > 0 )*/)) {88 if ( !lua_isstring(L,-1) ) { 76 89 return NULL; 77 90 } 78 datatype = PTP_CHDK_TYPE_ STRING;91 datatype = PTP_CHDK_TYPE_TABLE; 79 92 data = (char *)lua_tolstring(L,-1,&datasize); 80 93 lua_pop(L,1); 94 } 81 95 break; 82 96 default: … … 143 157 int i,end = lua_gettop(L); 144 158 for(i=1;i<=end; i++) { 159 ptp_script_msg *msg = lua_create_usb_msg(L,i,PTP_CHDK_S_MSGTYPE_RET); 145 160 // if the queue is full return values will be silently discarded 146 161 // incompatible types will be returned as TYPE_UNSUPPORTED to preserve expected number and order of return values 147 ptp_script_write_msg(lua_create_usb_msg(L,i,PTP_CHDK_S_MSGTYPE_RET)); 162 if(msg) { 163 ptp_script_write_msg(msg); 164 // create_usb_msg may convert the message to an error 165 if(msg->type != PTP_CHDK_S_MSGTYPE_RET) { 166 break; 167 } 168 } else { 169 ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, "error creating return msg"); 170 break; 171 } 148 172 } 149 173 } -
trunk/core/ptp.c
r1101 r1155 139 139 return 0; 140 140 } 141 // zero size messages don't make any sense 142 if(msg == NULL || msg->size == 0) { 141 if(msg == NULL) { 143 142 return 0; 144 143 } … … 159 158 160 159 // public interface for script 160 // create a message to be queued later 161 161 ptp_script_msg* ptp_script_create_msg(unsigned type, unsigned subtype, unsigned datasize, const void *data) { 162 162 ptp_script_msg *msg; 163 if(!datasize) {164 return NULL;165 }166 163 msg = malloc(sizeof(ptp_script_msg) + datasize); 167 164 msg->size = datasize; … … 169 166 msg->subtype = subtype; 170 167 // caller may fill in data themselves 171 if(data) { 168 // datasize may be empty (e.g. empty string) 169 if(data && datasize) { 172 170 memcpy(msg->data,data,msg->size); 173 171 } … … 175 173 } 176 174 175 // add a message to the outgoing queue 177 176 int ptp_script_write_msg(ptp_script_msg *msg) { 178 177 msg->script_id = script_run_id; … … 180 179 } 181 180 181 // retrieve the next message in the incoming queue 182 182 ptp_script_msg* ptp_script_read_msg(void) { 183 183 ptp_script_msg *msg; … … 197 197 } 198 198 } 199 200 // convenience function write an error message 199 201 int ptp_script_write_error_msg(unsigned errtype, const char *err) { 200 202 if(script_msg_q_full(&msg_q_out)) { … … 217 219 char *str; 218 220 } temp_data; 219 static int temp_data_kind = 0; // 0: nothing, 1: ascii string , 2: lua object220 static int temp_data_extra; // size (ascii string) or type (lua object)221 static int temp_data_kind = 0; // 0: nothing, 1: ascii string 222 static int temp_data_extra; // size (ascii string) 221 223 PTPContainer ptp; 222 224 … … 533 535 case PTP_CHDK_ReadScriptMsg: 534 536 { 537 char *pdata=""; 538 unsigned datasize=1; 539 535 540 ptp_script_msg *msg = dequeue_script_msg(&msg_q_out); 536 541 ptp.num_param = 4; 537 if(!msg) { 542 if(msg) { 543 ptp.param1 = msg->type; 544 ptp.param2 = msg->subtype; 545 ptp.param3 = msg->script_id; 546 ptp.param4 = msg->size; 547 // empty messages must have a data phase, so use default if no data 548 if(msg->size) { 549 datasize = msg->size; 550 pdata = msg->data; 551 } 552 } else { 538 553 // return a fully formed message for easier handling 539 554 ptp.param1 = PTP_CHDK_S_MSGTYPE_NONE; 540 555 ptp.param2 = 0; 541 556 ptp.param3 = 0; 542 ptp.param4 = 4; 543 // looks like we need to send some data no matter what 544 if ( !send_ptp_data(data,"\0\0\0",4) ) 545 { 546 ptp.code = PTP_RC_GeneralError; 547 } 548 break; 549 } 550 ptp.param1 = msg->type; 551 ptp.param2 = msg->subtype; 552 ptp.param3 = msg->script_id; 553 ptp.param4 = msg->size; 557 ptp.param4 = 0; 558 } 554 559 555 560 // NOTE message is lost if sending failed 556 if ( !send_ptp_data(data, msg->data,msg->size) )561 if ( !send_ptp_data(data,pdata,datasize) ) 557 562 { 558 563 ptp.code = PTP_RC_GeneralError; -
trunk/core/ptp.h
r1115 r1155 1 1 #ifndef __CHDK_PTP_H 2 2 #define __CHDK_PTP_H 3 #define PTP_CHDK_VERSION_MAJOR 1// increase only with backwards incompatible changes (and reset minor)3 #define PTP_CHDK_VERSION_MAJOR 2 // increase only with backwards incompatible changes (and reset minor) 4 4 #define PTP_CHDK_VERSION_MINOR 0 // increase with extensions of functionality 5 5 /* … … 8 8 0.2 - Added ScriptStatus and ScriptSupport, based on work by ultimA 9 9 1.0 - removed old script result code (luar), replace with message system 10 2.0 - return PTP_CHDK_TYPE_TABLE for tables instead of TYPE_STRING, allow return of empty strings 10 11 */ 11 12 … … 55 56 // for error ptp_chdk_script_error_type 56 57 // return param3 is script id of script that generated the message 57 // return param4 is length of the message data 58 // return param4 is length of the message data. 58 59 // return data is message. 59 // A minimum of 4 bytes of zeros is returned if there would not be data otherwise60 // A minimum of 1 bytes of zeros is returned if the message has no data (empty string or type NONE) 60 61 PTP_CHDK_WriteScriptMsg, // write a message for scripts running on camera 61 62 // input param2 is target script id, 0=don't care. Messages for a non-running script will be discarded … … 71 72 PTP_CHDK_TYPE_BOOLEAN, 72 73 PTP_CHDK_TYPE_INTEGER, 73 PTP_CHDK_TYPE_STRING, // NOTE tables currently returned as string 74 PTP_CHDK_TYPE_STRING, // Empty strings are returned with length=0 75 PTP_CHDK_TYPE_TABLE, // tables are converted to a string by usb_msg_table_to_string, 76 // this function can be overridden in lua to change the format 77 // the string may be empty for an empty table 74 78 } ptp_chdk_script_data_type; 75 79 … … 94 98 enum { 95 99 PTP_CHDK_S_MSGTYPE_NONE = 0, // no messages waiting 96 PTP_CHDK_S_MSGTYPE_ERR, // error message100 PTP_CHDK_S_MSGTYPE_ERR, // error message 97 101 PTP_CHDK_S_MSGTYPE_RET, // script return value 98 102 PTP_CHDK_S_MSGTYPE_USER, // message queued by script
Note: See TracChangeset
for help on using the changeset viewer.