diff --git a/canserver/4tests.txt b/canserver/4tests.txt new file mode 100644 index 0000000..f4f030c --- /dev/null +++ b/canserver/4tests.txt @@ -0,0 +1,10 @@ +#raw +register raw 0 raw +mesg raw 0x60a 32 1 96 0 0 0 0 0 + +#canopen +register x 0x58a canopen +mesg x 10 0x6001 0 + +#emul +register new 3333 emulation diff --git a/canserver/canopen.c b/canserver/canopen.c index a0e5bc1..89debd8 100644 --- a/canserver/canopen.c +++ b/canserver/canopen.c @@ -113,9 +113,13 @@ static CANmesg *mkMesg(SDO *sdo){ return &mesg; } -// transform CAN-message to SDO -SDO *parseSDO(CANmesg *mesg){ - static SDO sdo; +/** + * @brief parseSDO - transform CAN-message to SDO + * @param mesg (i) - message + * @param sdo (o) - SDO + * @return sdo or NULL depending on result + */ +SDO *parseSDO(CANmesg *mesg, SDO *sdo){ if(mesg->len != 8){ WARNX("Wrong SDO data length"); return NULL; @@ -125,17 +129,18 @@ SDO *parseSDO(CANmesg *mesg){ DBG("cobid=0x%X, not a TSDO!", cobid); return NULL; // not a transmit SDO } - sdo.NID = mesg->ID & NODEID_MASK; + sdo->NID = mesg->ID & NODEID_MASK; uint8_t spec = mesg->data[0]; - sdo.ccs = GET_CCS(spec); - sdo.index = (uint16_t)mesg->data[1] | ((uint16_t)mesg->data[2] << 8); - sdo.subindex = mesg->data[3]; - if((spec & SDO_E) && (spec & SDO_S)) sdo.datalen = SDO_datalen(spec); - else if(sdo.ccs == CCS_ABORT_TRANSFER) sdo.datalen = 4; // error code - else sdo.datalen = 0; // no data in message - for(uint8_t i = 0; i < sdo.datalen; ++i) sdo.data[i] = mesg->data[4+i]; - DBG("Got TSDO from NID=%d, ccs=%u, index=0x%X, subindex=0x%X, datalen=%d", sdo.NID, sdo.ccs, sdo.index, sdo.subindex, sdo.datalen); - return &sdo; + sdo->ccs = GET_CCS(spec); + sdo->index = (uint16_t)mesg->data[1] | ((uint16_t)mesg->data[2] << 8); + sdo->subindex = mesg->data[3]; + if((spec & SDO_E) && (spec & SDO_S)) sdo->datalen = SDO_datalen(spec); + else if(sdo->ccs == CCS_ABORT_TRANSFER) sdo->datalen = 4; // error code + else sdo->datalen = 0; // no data in message + for(uint8_t i = 0; i < sdo->datalen; ++i) sdo->data[i] = mesg->data[4+i]; + DBG("Got TSDO from NID=%d, ccs=%u, index=0x%X, subindex=0x%X, datalen=%d", + sdo->NID, sdo->ccs, sdo->index, sdo->subindex, sdo->datalen); + return sdo; } // send request to read SDO @@ -150,21 +155,23 @@ static int ask2read(uint16_t idx, uint8_t subidx, uint8_t NID){ return canbus_write(mesg); } -static SDO *getSDOans(uint16_t idx, uint8_t subidx, uint8_t NID){ +static SDO *getSDOans(uint16_t idx, uint8_t subidx, uint8_t NID, SDO *sdo){ FNAME(); + int found = 0; CANmesg mesg; - SDO *sdo = NULL; double t0 = dtime(); while(dtime() - t0 < SDO_ANS_TIMEOUT){ mesg.ID = TSDO_COBID | NID; // read only from given ID if(canbus_read(&mesg)){ continue; } - sdo = parseSDO(&mesg); - if(!sdo) continue; - if(sdo->index == idx && sdo->subindex == subidx) break; + if(!parseSDO(&mesg, sdo)) continue; + if(sdo->index == idx && sdo->subindex == subidx){ + found = 1; + break; + } } - if(!sdo || sdo->index != idx || sdo->subindex != subidx){ + if(!found){ WARNX("No answer from SDO 0x%X/0x%X", idx, subidx); return NULL; } @@ -176,15 +183,16 @@ static SDO *getSDOans(uint16_t idx, uint8_t subidx, uint8_t NID){ * @param idx - SDO index * @param subidx - SDO subindex * @param NID - target node ID + * @param sdo (i)- SDO to fit * @return SDO received or NULL if error */ -SDO *readSDOvalue(uint16_t idx, uint8_t subidx, uint8_t NID){ +SDO *readSDOvalue(uint16_t idx, uint8_t subidx, uint8_t NID, SDO *sdo){ FNAME(); if(ask2read(idx, subidx, NID)){ WARNX("readSDOvalue(): Can't initiate upload"); return NULL; } - return getSDOans(idx, subidx, NID); + return getSDOans(idx, subidx, NID, sdo); } static inline uint32_t mku32(uint8_t data[4]){ @@ -214,42 +222,42 @@ static inline int8_t mki8(uint8_t data[4]){ // read SDO value, if error - return INT64_MIN int64_t SDO_read(const SDO_dic_entry *e, uint8_t NID){ FNAME(); - SDO *sdo = readSDOvalue(e->index, e->subindex, NID); - if(!sdo){ + SDO sdo; + if(!readSDOvalue(e->index, e->subindex, NID, &sdo)){ return INT64_MIN; } - if(sdo->ccs == CCS_ABORT_TRANSFER){ // error + if(sdo.ccs == CCS_ABORT_TRANSFER){ // error WARNX("Got error for SDO 0x%X", e->index); - uint32_t ac = mku32(sdo->data); + uint32_t ac = mku32(sdo.data); const char *etxt = abortcode_text(ac); if(etxt) WARNX("Abort code 0x%X: %s", ac, etxt); return INT64_MIN; } - if(sdo->datalen != e->datasize){ - WARNX("Got SDO with length %d instead of %d (as in dictionary)", sdo->datalen, e->datasize); + if(sdo.datalen != e->datasize){ + WARNX("Got SDO with length %d instead of %d (as in dictionary)", sdo.datalen, e->datasize); } int64_t ans = 0; if(e->issigned){ - switch(sdo->datalen){ + switch(sdo.datalen){ case 1: - ans = mki8(sdo->data); + ans = mki8(sdo.data); break; case 4: - ans = mki32(sdo->data); + ans = mki32(sdo.data); break; default: // can't be 3! 3->2 - ans = mki16(sdo->data); + ans = mki16(sdo.data); } }else{ - switch(sdo->datalen){ + switch(sdo.datalen){ case 1: - ans = mku8(sdo->data); + ans = mku8(sdo.data); break; case 4: - ans = mku32(sdo->data); + ans = mku32(sdo.data); break; default: // can't be 3! 3->2 - ans = mku16(sdo->data); + ans = mku16(sdo.data); } } return ans; @@ -276,23 +284,23 @@ int SDO_writeArr(const SDO_dic_entry *e, uint8_t NID, const uint8_t *data){ return 2; } DBG("get answer"); - SDO *sdop = getSDOans(e->index, e->subindex, NID); - if(!sdop){ + SDO sdop; + if(!getSDOans(e->index, e->subindex, NID, &sdop)){ WARNX("SDO_write(): SDO read error"); return 3; } - if(sdop->ccs == CCS_ABORT_TRANSFER){ // error + if(sdop.ccs == CCS_ABORT_TRANSFER){ // error WARNX("SDO_write(): Got error for SDO 0x%X", e->index); - uint32_t ac = mku32(sdop->data); + uint32_t ac = mku32(sdop.data); const char *etxt = abortcode_text(ac); if(etxt) WARNX("Abort code 0x%X: %s", ac, etxt); return 4; } - if(sdop->datalen != 0){ + if(sdop.datalen != 0){ WARNX("SDO_write(): got answer with non-zero length"); return 5; } - if(sdop->ccs != CCS_SEG_UPLOAD){ + if(sdop.ccs != CCS_SEG_UPLOAD){ WARNX("SDO_write(): got wrong answer"); return 6; } diff --git a/canserver/canopen.h b/canserver/canopen.h index 2c01c78..dc8563c 100644 --- a/canserver/canopen.h +++ b/canserver/canopen.h @@ -78,8 +78,8 @@ typedef struct{ } SDO; const char *abortcode_text(uint32_t abortcode); -SDO *parseSDO(CANmesg *mesg); -SDO *readSDOvalue(uint16_t idx, uint8_t subidx, uint8_t NID); +SDO *parseSDO(CANmesg *mesg, SDO *sdo); +SDO *readSDOvalue(uint16_t idx, uint8_t subidx, uint8_t NID, SDO *sdo); int64_t SDO_read(const SDO_dic_entry *e, uint8_t NID); diff --git a/canserver/main.c b/canserver/main.c index e6321df..3bb962e 100644 --- a/canserver/main.c +++ b/canserver/main.c @@ -91,12 +91,6 @@ int main(int argc, char **argv){ } } #endif - - /* - * INSERT CODE HERE - * connection check & device validation - */ - //if(!G->terminal) signals(15); // there's not main controller connected to given terminal daemonize(GP->port); return 0; } diff --git a/canserver/processmotors.c b/canserver/processmotors.c index e2b4214..594dea0 100644 --- a/canserver/processmotors.c +++ b/canserver/processmotors.c @@ -17,7 +17,6 @@ */ #include "aux.h" -#include "canbus.h" #include "canopen.h" #include "cmdlnopts.h" #include "processmotors.h" @@ -34,7 +33,9 @@ static int CANspeed = 0; // default speed, if !=0 set it when connected // all messages are in format "ID [data]" -message CANbusMessages = {0}; // CANserver thread is master +static message CANbusMessages = {0}; // CANserver thread is master +#define CANBUSPUSH(mesg) mesgAddObj(&CANbusMessages, mesg, sizeof(CANmesg)) +#define CANBUSPOP() mesgGetObj(&CANbusMessages, NULL) // basic threads // messages: master - thread, slave - caller @@ -113,18 +114,33 @@ static void reopen_device(){ // do something with can message: send to receiver static void processCANmessage(CANmesg *mesg){ - threadinfo *ti = findThreadByID(mesg->ID); - if(!ti) return; - DBG("Found"); - char buf[64], *ptr = buf; - int l = 64, x; - x = snprintf(ptr, l, "#0x%03X ", mesg->ID); - l -= x; ptr += x; - for(int i = 0; i < mesg->len; ++i){ - x = snprintf(ptr, l, "0x%02X ", mesg->data[i]); + threadinfo *ti = findThreadByID(0); + if(ti){ + /*char buf[64], *ptr = buf; + int l = 64, x; + x = snprintf(ptr, l, "#0x%03X ", cm.ID); l -= x; ptr += x; + for(int i = 0; i < cm.len; ++i){ + x = snprintf(ptr, l, "0x%02X ", cm.data[i]); + l -= x; ptr += x; + }*/ + mesgAddObj(&ti->answers, (void*)mesg, sizeof(CANmesg)); + } + ti = findThreadByID(mesg->ID); + if(ti){ + /* DBG("Found"); + char buf[64], *ptr = buf; + int l = 64, x; + x = snprintf(ptr, l, "#0x%03X ", mesg->ID); + l -= x; ptr += x; + for(int i = 0; i < mesg->len; ++i){ + x = snprintf(ptr, l, "0x%02X ", mesg->data[i]); + l -= x; ptr += x; + } + mesgAddText(&ti->answers, buf); + */ + mesgAddObj(&ti->answers, (void*) mesg, sizeof(CANmesg)); } - addmesg(&ti->answers, buf); } /** @@ -135,37 +151,19 @@ static void processCANmessage(CANmesg *mesg){ void *CANserver(_U_ void *data){ reopen_device(); while(1){ - CANmesg cm; - char *mesg = getmesg(&CANbusMessages); - if(mesg){ - if(parsePacket(&cm, mesg)){ - LOGMSG("Received wrong CAN message: %s", mesg); - DBG("Bad message: %s", mesg); - }else{ - if(canbus_write(&cm)){ - LOGWARN("Can't write to CANbus, try to reopen"); - WARNX("Can't write to canbus"); - if(canbus_disconnected()) reopen_device(); - } + CANmesg *msg = CANBUSPOP(); + if(msg){ + if(canbus_write(msg)){ + LOGWARN("Can't write to CANbus, try to reopen"); + WARNX("Can't write to canbus"); + if(canbus_disconnected()) reopen_device(); } - FREE(mesg); + FREE(msg); } usleep(1000); + CANmesg cm; if(!canbus_read(&cm)){ // got raw message from CAN bus - parce it DBG("Got CAN message from %d, len: %d", cm.ID, cm.len); - // send raw message to 0 - threadinfo *ti = findThreadByID(0); - if(ti){ - char buf[64], *ptr = buf; - int l = 64, x; - x = snprintf(ptr, l, "#0x%03X ", cm.ID); - l -= x; ptr += x; - for(int i = 0; i < cm.len; ++i){ - x = snprintf(ptr, l, "0x%02X ", cm.data[i]); - l -= x; ptr += x; - } - addmesg(&ti->answers, buf); - } processCANmessage(&cm); }else if(canbus_disconnected()) reopen_device(); } @@ -181,19 +179,19 @@ void *CANserver(_U_ void *data){ static void *stpemulator(void *arg){ threadinfo *ti = (threadinfo*)arg; while(1){ - char *mesg = getmesg(&ti->commands); + char *mesg = mesgGetText(&ti->commands); if(mesg){ DBG("Stepper emulator got: %s", mesg); - addmesg(&ServerMessages, mesg); + mesgAddText(&ServerMessages, mesg); /* do something */ FREE(mesg); } int r100 = rand() % 10000; - if(r100 < 20){ // 20% of probability - addmesg(&ServerMessages, "stpemulator works fine!"); + if(r100 < 1){ // 10% of probability + mesgAddText(&ServerMessages, "stpemulator works fine!"); } if(r100 > 9998){ - addmesg(&ServerMessages, "O that's good!"); + mesgAddText(&ServerMessages, "O that's good!"); } usleep(1000); } @@ -211,16 +209,25 @@ static void *stpemulator(void *arg){ static void *rawcommands(void *arg){ threadinfo *ti = (threadinfo*)arg; while(1){ - char *mesg = getmesg(&ti->commands); + char *mesg = mesgGetText(&ti->commands); if(mesg){ DBG("Got raw command: %s", mesg); - addmesg(&CANbusMessages, mesg); + CANmesg cm; + if(!parsePacket(&cm, mesg)) CANBUSPUSH(&cm); FREE(mesg); } - mesg = getmesg(&ti->answers); - if(mesg){ // got raw answer from bus to thread ID, send it to all - addmesg(&ServerMessages, mesg); - FREE(mesg); + CANmesg *ans = (CANmesg*) mesgGetObj(&ti->answers, NULL); + if(ans){ // got raw answer from bus to thread ID, send it to all + char buf[64], *ptr = buf; + int l = 64, x; + x = snprintf(ptr, l, "#0x%03X ", ans->ID); + l -= x; ptr += x; + for(int i = 0; i < ans->len; ++i){ + x = snprintf(ptr, l, "0x%02X ", ans->data[i]); + l -= x; ptr += x; + } + mesgAddText(&ServerMessages, buf); + FREE(ans); } usleep(1000); } @@ -245,25 +252,19 @@ static void sendSDO(char *mesg){ } DBG("User's message have %d ints", N); - uint8_t data[8] = {0}, datalen = (uint8_t) N - 3; - data[0] = SDO_CCS(CCS_INIT_DOWNLOAD); + CANmesg comesg; + uint8_t datalen = (uint8_t) N - 3; + comesg.data[0] = SDO_CCS(CCS_INIT_DOWNLOAD); + comesg.len = 8; if(datalen){ // there's data - data[0] |= SDO_N(datalen) | SDO_E | SDO_S; - for(int i = 0; i < datalen; ++i) data[4+i] = (uint8_t)(info[3+i]); + comesg.data[0] |= SDO_N(datalen) | SDO_E | SDO_S; + for(int i = 0; i < datalen; ++i) comesg.data[4+i] = (uint8_t)(info[3+i]); } - data[1] = info[1] & 0xff; - data[2] = (info[1] >> 8) & 0xff; - data[3] = (uint8_t)(info[2]); - - char buf[64], *ptr = buf; - int l = 64, x; - x = snprintf(ptr, l, "0x%03X ", (uint16_t)(RSDO_COBID + info[0])); - l -= x; ptr += x; - for(int i = 0; i < 8; ++i){ - x = snprintf(ptr, l, "0x%02X ", (uint16_t)(data[i])); - l -= x; ptr += x; - } - addmesg(&CANbusMessages, buf); + comesg.data[1] = info[1] & 0xff; + comesg.data[2] = (info[1] >> 8) & 0xff; + comesg.data[3] = (uint8_t)(info[2]); + comesg.ID = (uint16_t)(RSDO_COBID + info[0]); + CANBUSPUSH(&comesg); } // send raw CANopen commands @@ -271,16 +272,36 @@ static void sendSDO(char *mesg){ static void *canopencmds(void *arg){ threadinfo *ti = (threadinfo*)arg; while(1){ - char *mesg = getmesg(&ti->commands); + char *mesg = mesgGetText(&ti->commands); if(mesg) do{ DBG("Got CANopen command: %s", mesg); sendSDO(mesg); FREE(mesg); }while(0); - mesg = getmesg(&ti->answers); - if(mesg){ // got raw answer from bus to thread ID, analize it -addmesg(&ServerMessages, mesg); - FREE(mesg); + CANmesg *ans = (CANmesg*)mesgGetObj(&ti->answers, NULL); + if(ans){ // got raw answer from bus to thread ID, analize it + SDO sdo; + if(parseSDO(ans, &sdo)){ + char buf[128], *ptr = buf; + int rest = 128; + int l = snprintf(ptr, rest, "SDO={nid=0x%02X, idx=0x%04X, subidx=%d, ccs=0x%02X, datalen=%d", + sdo.NID, sdo.index, sdo.subindex, sdo.ccs, sdo.datalen); + ptr += l; rest -= l; + if(sdo.datalen){ + l = snprintf(ptr, rest, ", data=["); + ptr += l; rest -= l; + for(int idx = 0; idx < sdo.datalen; ++idx){ + if(idx) l = snprintf(ptr, rest, ", 0x%02X", sdo.data[idx]); + else l = snprintf(ptr, rest, "0x%02X", sdo.data[idx]); + ptr += l; rest -= l; + } + l = snprintf(ptr, rest, "]"); + ptr += l; rest -= l; + } + snprintf(ptr, rest, "}"); + mesgAddText(&ServerMessages, buf); + } + FREE(ans); } usleep(1000); } diff --git a/canserver/processmotors.h b/canserver/processmotors.h index 4662b6e..c2a5936 100644 --- a/canserver/processmotors.h +++ b/canserver/processmotors.h @@ -20,9 +20,9 @@ #ifndef PROCESSMOTORS_H__ #define PROCESSMOTORS_H__ +#include "canbus.h" #include "threadlist.h" -extern message CANbusMessages; extern thread_handler CANhandlers[]; void *CANserver(void *data); diff --git a/canserver/proto.c b/canserver/proto.c index 4e26fa8..eebccdc 100644 --- a/canserver/proto.c +++ b/canserver/proto.c @@ -73,7 +73,7 @@ static const char *listthr(_U_ char *par1, _U_ char *par2){ list = nextThread(list); if(!list) break; snprintf(msg, 256, "thread name='%s' role='%s' ID=0x%X", list->ti.name, list->ti.handler.name, list->ti.ID); - addmesg(&ServerMessages, msg); + mesgAddText(&ServerMessages, msg); empty = 0; }while(1); if(empty) return "No threads"; @@ -132,7 +132,7 @@ static const char *sendmsg(char *thrname, char *data){ FNAME(); threadinfo *ti = findThreadByName(thrname); if(!ti) return ANS_NOTFOUND; - if(!addmesg(&ti->commands, data)) return ANS_CANTSEND; + if(!mesgAddText(&ti->commands, data)) return ANS_CANTSEND; return ANS_OK; } diff --git a/canserver/socket.c b/canserver/socket.c index b648359..092890f 100644 --- a/canserver/socket.c +++ b/canserver/socket.c @@ -153,7 +153,7 @@ static void *server(void *asock){ } } } // endfor - char *srvmesg = getmesg(&ServerMessages); // broadcast messages to all clients + char *srvmesg = mesgGetText(&ServerMessages); // broadcast messages to all clients if(srvmesg){ // send broadcast message to all clients or throw them to /dev/null for(int fdidx = 1; fdidx < nfd; ++fdidx){ send_data(poll_set[fdidx].fd, srvmesg); diff --git a/canserver/threadlist.c b/canserver/threadlist.c index 67105a7..6b4ba7a 100644 --- a/canserver/threadlist.c +++ b/canserver/threadlist.c @@ -32,16 +32,18 @@ static threadlist *thelist = NULL; * @param v (i) - data to push * @return pointer to just pushed node */ -static msglist *pushmessage(msglist **lst, char *v){ +static msglist *pushmessage(msglist **lst, void *v, size_t size){ if(!lst || !v) return NULL; msglist *node; if((node = MALLOC(msglist, 1)) == 0) return NULL; // allocation error - node->data = strdup(v); + node->data = malloc(size); if(!node->data){ FREE(node); return NULL; } + memcpy(node->data, v, size); + node->size = size; if(!*lst){ *lst = node; (*lst)->last = node; @@ -55,14 +57,16 @@ static msglist *pushmessage(msglist **lst, char *v){ /** * @brief popmessage - get data from head of list * @param lst (io) - list + * @param size (o) - data size * @return data from first node or NULL if absent (SHOULD BE FREEd AFER USAGE!) */ -static char *popmessage(msglist **lst){ +static void *popmessage(msglist **lst, size_t *size){ if(!lst || !*lst) return NULL; char *ret; msglist *node = *lst; if(node->next) node->next->last = node->last; // pop not last message ret = node->data; + if(size) *size = node->size; *lst = node->next; FREE(node); return ret; @@ -115,18 +119,17 @@ threadinfo *findThreadByID(int ID){ } /** - * @brief addmesg - add message to thread's queue - * @param msg - message itself - * @param txt - data to add - * @return data added or NULL if failed + * @brief mesgAddObj - add any object to message + * @param msg (i) - message + * @param data (i) - any data + * @param size - it's size + * @return pointer to message data if success (NULL if failed) */ -char *addmesg(message *msg, char *txt){ - if(!msg) return NULL; - size_t L = strlen(txt); - if(L < 1) return NULL; - DBG("Want to add mesg '%s' with length %zd", txt, L); +void *mesgAddObj(message *msg, void *data, size_t size){ + if(!msg || !data || size == 0) return NULL; + DBG("Want to add mesg with length %zd", size); if(pthread_mutex_lock(&msg->mutex)) return NULL; - msglist *node = pushmessage(&msg->text, txt); + msglist *node = pushmessage(&msg->msg, data, size); if(!node){ pthread_mutex_unlock(&msg->mutex); return NULL; @@ -136,19 +139,42 @@ char *addmesg(message *msg, char *txt){ } /** - * @brief getmesg - get first message from queue (allocates data, should be free'd after usage!) + * @brief mesgAddText - add message to thread's queue * @param msg - message itself - * @return data or NULL if empty + * @param txt - data to add + * @return data added or NULL if failed */ -char *getmesg(message *msg){ +char *mesgAddText(message *msg, char *txt){ + if(!txt) return NULL; + DBG("mesg add text '%s'", txt); + size_t l = strlen(txt) + 1; + return mesgAddObj(msg, (void*)txt, l); +} + +/** + * @brief mesgGetObj - get object from message + * @param msg (i) - message + * @param size (o) - object's size or NULL + * @return pointer to object or NULL if absent + */ +void *mesgGetObj(message *msg, size_t *size){ if(!msg) return NULL; char *text = NULL; if(pthread_mutex_lock(&msg->mutex)) return NULL; - text = popmessage(&msg->text); + text = popmessage(&msg->msg, size); pthread_mutex_unlock(&msg->mutex); return text; } +/** + * @brief mesgGetText - get first message from queue (allocates data, should be free'd after usage!) + * @param msg - message itself + * @return data or NULL if empty + */ +char *mesgGetText(message *msg){ + return (char*) mesgGetObj(msg, NULL); +} + /** * @brief registerThread - register new thread * @param name - thread name @@ -212,10 +238,10 @@ int killThread(threadlist *lptr, threadlist *prev){ else if(prev) prev->next = next; char *txt; pthread_mutex_lock(&lptr->ti.commands.mutex); - while((txt = popmessage(&lptr->ti.commands.text))) FREE(txt); + while((txt = popmessage(&lptr->ti.commands.msg, NULL))) FREE(txt); pthread_mutex_destroy(&lptr->ti.commands.mutex); pthread_mutex_lock(&lptr->ti.answers.mutex); - while((txt = popmessage(&lptr->ti.answers.text))) FREE(txt); + while((txt = popmessage(&lptr->ti.answers.msg, NULL))) FREE(txt); pthread_mutex_destroy(&lptr->ti.answers.mutex); if(pthread_cancel(lptr->ti.thread)) WARN("Can't kill thread '%s'", lptr->ti.name); FREE(lptr); diff --git a/canserver/threadlist.h b/canserver/threadlist.h index 0510374..7fcae3d 100644 --- a/canserver/threadlist.h +++ b/canserver/threadlist.h @@ -27,13 +27,14 @@ // messages FIFO typedef struct msglist_{ - char *data; // message itself + void *data; // message itself + size_t size; // message length in bytes struct msglist_ *next, *last; // other elements of list } msglist; // interthread messages; index 0 - MOSI, index 1 - MISO typedef struct{ - msglist *text; // stringified text messages + msglist *msg; // stringified text messages pthread_mutex_t mutex; // text changing mutex } message; @@ -47,8 +48,8 @@ typedef struct{ typedef struct{ char name[THREADNAMEMAXLEN+1]; // thread name int ID; // numeric ID (canopen ID) - message commands; // commands from clients - message answers; // answers from CANserver (raw messages to given ID) + message commands; // commands from clients (char *) + message answers; // answers from CANserver (CANmesg *) pthread_t thread; // thread descriptor thread_handler handler; // handler name & function } threadinfo; @@ -64,7 +65,9 @@ threadinfo *findThreadByID(int ID); threadinfo *registerThread(char *name, int ID, thread_handler *handler); threadlist *nextThread(threadlist *curr); int killThreadByName(const char *name); -char *getmesg(message *msg); -char *addmesg(message *msg, char *txt); +char *mesgGetText(message *msg); +char *mesgAddText(message *msg, char *txt); +void *mesgGetObj(message *msg, size_t *size); +void *mesgAddObj(message *msg, void *data, size_t size); #endif // THREADLIST_H__