void _xcb_out_send_sync(xcb_connection_t *c) { /* wait for other writing threads to get out of my way. */ while(c->out.writing) pthread_cond_wait(&c->out.cond, &c->iolock); get_socket_back(c); send_sync(c); }
/*{{{ log_start -- begin logging, send output to 'file'*/ int log_start(FILE *file) { if (do_save == 0 && file) { share_file = file; do_save = 1; send_sync(); return (1); } else return (0); }
// somewhat counterintuitively, this returns NULL if everything's ok. char * create_trigger(zhash_t * triggers, char * rule_id, zctx_t * context, triggerconfig_t * tconf) { void * trigger_pipe = zthread_fork(context, trigger, tconf); send_sync("ping", trigger_pipe); char * pipe_resp = zstr_recv(trigger_pipe); if(strcmp(pipe_resp, "pong") == 0) { zhash_insert(triggers, rule_id, trigger_pipe); free(pipe_resp); return NULL; } else { zclock_log("something went wrong creating a trigger: %s", pipe_resp); return pipe_resp; } }
void add_monitor(rulepackage_t * rpkg, zmsg_t * reply) { // unconditionally fork a monitor for each line // they'll die when they get a channel change int i; for(i=1; i<4; i++) { monitorconfig_t * mconf = malloc(sizeof(monitorconfig_t)); mconf->line_id = i; mconf->source_worker = rpkg->servicename; mconf->out_socket = rpkg->base_config->portwatcher_endpoint; mconf->channel = rpkg->channel; void * monitor_pipe = zthread_fork(rpkg->context, watch_port, (void*)mconf); send_sync("ping", monitor_pipe); recv_sync("pong", monitor_pipe); zsocket_destroy(rpkg->context, monitor_pipe); } zmsg_pushstr(reply, "ok"); }
void generic_worker(void * cvoid, zctx_t * context, void * pipe) { workerconfig_t *config = (workerconfig_t*) cvoid; zhash_t * rules = zhash_new(); child_handshake(pipe); zmsg_t *reply = NULL; void * rule_pipe = NULL; char * ninja = config->base_config->identity; char * channel = config->channel; char * servicename = malloc(strlen(ninja) + strlen(channel) + 2); sprintf(servicename, "%s:%s", ninja,channel); // sqlite stuff int rc; char * tail = NULL; sqlite3 *db = init_db(servicename); sqlite3_stmt * insert_stmt; zclock_log("%s worker preparing rules...", servicename); sqlite3_prepare_v2(db, "insert into rules VALUES (@RULEID, @TRIGGER_NAME, @TARGET_WORKER, @AUTH, @ADDINS);", 512, &insert_stmt, NULL); zclock_log("%s worker reloading rules...", servicename); reload_rules(context, db, servicename, channel, rules); zclock_log("%s worker connecting...", servicename); mdwrk_t *session = mdwrk_new (config->base_config->broker_endpoint, servicename, 0); zclock_log("%s worker connected!", servicename); while (1) { zclock_log("%s worker waiting for work.", servicename); zmsg_t *request = mdwrk_recv (session, &reply); if (request == NULL) break; // Worker was interrupted char * command = zmsg_popstr(request); char * rule_id = zmsg_popstr(request); zclock_log("%s worker servicing request %s for rule %s", servicename,command,rule_id); reply = zmsg_new(); if (strcmp(command, "AddTrigger") == 0) { zclock_log("new trigger!"); if (zhash_lookup(rules, rule_id)) { // already have a rule with that id! WTF?? // FIXME should probably delete this and reinstate zclock_log("Received duplicate rule %s, ignoring", rule_id); zmsg_destroy(&request); zmsg_pushstr(reply, "duplicate"); } else { triggerconfig_t * tconf = malloc(sizeof(triggerconfig_t)); create_triggerconfig(tconf, request, channel, rule_id); char * created = create_trigger(rules, rule_id, context, tconf); if(NULL == created) { // happy path, so add to db sqlite3_bind_text(insert_stmt, 1, tconf->rule_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 2, tconf->trigger_name, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 3, tconf->target_worker, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 4, tconf->auth, -1, SQLITE_TRANSIENT); sqlite3_bind_text(insert_stmt, 5, tconf->addins, -1, SQLITE_TRANSIENT); sqlite3_step(insert_stmt); sqlite3_clear_bindings(insert_stmt); sqlite3_reset(insert_stmt); zmsg_pushstr(reply, "ok"); } else { zclock_log("create_trigger failed: %s", created); zmsg_pushstr(reply, created); } free(created); } } else if (strcmp(command,"RemoveRule") == 0) { if (rule_pipe=zhash_lookup(rules, rule_id)) { // found it zclock_log("rule %s exists, removing.", rule_id); send_sync("Destroy",rule_pipe); zclock_log("rule %s waiting for OK from pipe", rule_id); recv_sync("ok", rule_pipe); zsocket_destroy(context, rule_pipe); zhash_delete(rules, rule_id); zmsg_pushstr(reply, "ok"); zclock_log("rule %s completely destroyed", rule_id); } else { // not there! zclock_log("Received delete trigger request for nonexistent rule %s, ignoring", rule_id); zmsg_pushstr(reply, "rule not found"); } } else if (strcmp(command, "AddMonitor")==0) { // unconditionally fork a monitor for each line // they'll die when they get a channel change int i; for(i=1; i<4; i++) { monitorconfig_t * mconf = malloc(sizeof(monitorconfig_t)); mconf->line_id = i; mconf->source_worker = servicename; mconf->out_socket = config->base_config->portwatcher_endpoint; mconf->channel = channel; void * monitor_pipe = zthread_fork(context, watch_port, (void*)mconf); send_sync("ping", monitor_pipe); recv_sync("pong", monitor_pipe); zsocket_destroy(context, monitor_pipe); } zmsg_pushstr(reply, "ok"); } else { zclock_log("Can't handle command %s: ignoring", command); } zmsg_destroy(&request); } mdwrk_destroy (&session); return; }
static int set_new_event( int t ) { int ptr; unsigned char *data; int count; int follower; __GETMDX; data = mdx->data; ptr = mdx->track[t].current_mml_ptr; count = 0; follower = 0; #if 0 if ( ptr+1 <= mdx->length && t>7 ) { fprintf(stderr,"%2d %2x %2x\n",t,data[ptr],data[ptr+1]); fflush(stderr); } #endif if ( data[ptr] <= MDX_MAX_REST ) { /* rest */ note_off(t); count = data[ptr]+1; mdx->track[t].gate = count+1; follower=0; } else if ( data[ptr] <= MDX_MAX_NOTE ) { /* note */ note_on( t, data[ptr]); count = data[ptr+1]+1; do_quantize( t, count ); follower = 1; } else { switch ( data[ptr] ) { case MDX_SET_TEMPO: set_tempo( data[ptr+1] ); follower = 1; break; case MDX_SET_OPM_REG: set_opm_reg( t, data[ptr+1], data[ptr+2] ); follower = 2; break; case MDX_SET_VOICE: set_voice( t, data[ptr+1] ); follower = 1; break; case MDX_SET_PHASE: set_phase( t, data[ptr+1] ); follower = 1; break; case MDX_SET_VOLUME: set_volume( t, data[ptr+1] ); follower = 1; break; case MDX_VOLUME_DEC: dec_volume( t ); follower = 0; break; case MDX_VOLUME_INC: inc_volume( t ); follower = 0; break; case MDX_SET_QUANTIZE: set_quantize( t, data[ptr+1] ); follower = 1; break; case MDX_SET_KEYOFF: set_keyoff( t ); follower = 0; break; case MDX_REPEAT_START: mdx->track[t].loop_counter[mdx->track[t].loop_depth] = data[ptr+1]; if ( mdx->track[t].loop_depth < MDX_MAX_LOOP_DEPTH ) mdx->track[t].loop_depth++; follower = 2; break; case MDX_REPEAT_END: if (--mdx->track[t].loop_counter[mdx->track[t].loop_depth-1] == 0 ) { if ( --mdx->track[t].loop_depth < 0 ) mdx->track[t].loop_depth=0; } else { if ( data[ptr+1] >= 0x80 ) { ptr = ptr+2 - (0x10000-(data[ptr+1]*256 + data[ptr+2])) - 2; } else { ptr = ptr+2 + data[ptr+1]*256 + data[ptr+2] - 2; } } follower = 2; break; case MDX_REPEAT_BREAK: if ( mdx->track[t].loop_counter[mdx->track[t].loop_depth-1] == 1 ) { if ( --mdx->track[t].loop_depth < 0 ) mdx->track[t].loop_depth=0; ptr = ptr+2 + data[ptr+1]*256 + data[ptr+2] -2 +2; } follower = 2; break; case MDX_SET_DETUNE: set_detune( t, data[ptr+1], data[ptr+2] ); follower = 2; break; case MDX_SET_PORTAMENT: set_portament( t, data[ptr+1], data[ptr+2] ); follower = 2; break; case MDX_DATA_END: if ( data[ptr+1] == 0x00 ) { count = -1; note_off(t); follower = 1; } else { ptr = ptr+2 - (0x10000-(data[ptr+1]*256 + data[ptr+2])) - 2; mdx->track[t].infinite_loop_times++; follower = 2; } break; case MDX_KEY_ON_DELAY: follower = 1; break; case MDX_SEND_SYNC: send_sync( data[ptr+1] ); follower = 1; break; case MDX_RECV_SYNC: recv_sync( t ); follower = 0; count = 1; break; case MDX_SET_FREQ: set_freq( t, data[ptr+1] ); follower = 1; break; case MDX_SET_PLFO: if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) { set_plfo_onoff( t, data[ptr+1]-0x80 ); follower = 1; } else { set_plfo( t, data[ptr+1], data[ptr+2], data[ptr+3], data[ptr+4], data[ptr+5] ); follower = 5; } break; case MDX_SET_ALFO: if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) { set_alfo_onoff( t, data[ptr+1]-0x80 ); follower = 1; } else { set_alfo( t, data[ptr+1], data[ptr+2], data[ptr+3], data[ptr+4], data[ptr+5] ); follower = 5; } break; case MDX_SET_OPMLFO: if ( data[ptr+1] == 0x80 || data[ptr+1] == 0x81 ) { set_hlfo_onoff( t, data[ptr+1]-0x80 ); follower = 1; } else { set_hlfo( t, data[ptr+1], data[ptr+2], data[ptr+3], data[ptr+4], data[ptr+5] ); follower = 5; } break; case MDX_SET_LFO_DELAY: set_lfo_delay( t, data[ptr+1] ); follower = 1; break; case MDX_SET_PCM8_MODE: follower = 0; break; case MDX_FADE_OUT: if ( data[ptr+1]==0x00 ) { follower = 1; set_fade_out( 5 ); } else { follower = 2; set_fade_out( data[ptr+2] ); } break; default: count = -1; break; } } ptr += 1+follower; mdx->track[t].current_mml_ptr = ptr; return count; }
uint32_t uIPMain(void) { uint32_t i; uip_ipaddr_t ipaddr; struct timer periodic_timer, arp_timer, can_sync_timer; LED_On(2); // Sys timer init 1/100 sec tick clock_init(2); timer_set(&periodic_timer, CLOCK_SECOND / 10); timer_set(&arp_timer, CLOCK_SECOND * 10); timer_set(&can_sync_timer, CLOCK_SECOND / 8); //ca. 1x pro sec wird gesynced // Initialize the ethernet device driver // Init MAC // Phy network negotiation tapdev_init(); //code in: ENET_TxDscrInit (ethernet.c) & ENET_RxDscrInit (ethernet.c) & ETH_Start (stm32_eth.c) // Initialize the uIP TCP/IP stack. uip_init(); //code in uip.c // Init Server #ifdef TEST_GATEWAY uip_ipaddr(ipaddr, 10,0,241,2); #else uip_ipaddr(ipaddr, 10,0,241,1); #endif uip_sethostaddr(ipaddr); //ip uip_ipaddr(ipaddr, 10,0,240,0); uip_setdraddr(ipaddr); //gw uip_ipaddr(ipaddr, 255,255,252,0); uip_setnetmask(ipaddr); //nm // Initialize the server listen on port 23 uip_listen(HTONS(23)); //turn led off, we are now ready for inncoming conenctions LED_Off(1); CanRxMsg RxMessage; int can_last_msg_id = 0; uint32_t nCount; while(1) { if(timer_expired(&can_sync_timer)) { nCount++; timer_reset(&can_sync_timer); #ifndef TEST_GATEWAY send_sync( nCount % 2 ); if( nCount % 2 == 1 ) LED_On(2); else LED_Off(2); #endif } // ethernet stuff uip_len = tapdev_read(uip_buf); if(uip_len > 0) //read input { if(BUF->type == htons(UIP_ETHTYPE_IP)) //Layer3? { uip_arp_ipin(); uip_input(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); //get ARP of destination - or default gw (uip_arp.c) tapdev_send(uip_buf,uip_len); } } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) //Layer2? { uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { tapdev_send(uip_buf,uip_len); } } } else if(timer_expired(&periodic_timer)) //check if there is data in the send queue of each connection and send it { timer_reset(&periodic_timer); for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); //sets uip_conn to the current connections (macro uip.h) /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); //get ARP of destination - or default gw (uip_arp.c) tapdev_send(uip_buf,uip_len); } } #if UIP_UDP for(i = 0; i < UIP_UDP_CONNS; i++) { uip_udp_periodic(i); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); //get ARP of destination - or default gw (uip_arp.c) tapdev_send(); } } #endif /* UIP_UDP */ /* Call the ARP timer function every 10 seconds. */ /* It updates the arp-table (removes old entries) */ if(timer_expired(&arp_timer)) { timer_reset(&arp_timer); uip_arp_timer(); } } } return(TRUE); }
/** * returns the status of the execution * 0 = normal end * 1 = expect mismatch */ int execute_script(int sockfd, registry_t *script) { // current "pc" pointer to script line int curpos = 0; line_t *line = NULL; int lineno = 0; int err = 0; ssize_t size = 0; line_t *errmsg = NULL; scriptlet_t *scr = NULL; while ( (err == 0) && (line = reg_get(script, curpos)) != NULL) { lineno = line->num; switch (line->cmd) { case CMD_COMMENT: if (!trace) { break; } // fall-through case CMD_MESSAGE: log_info("> %s\n", line->buffer); break; case CMD_ERRMSG: errmsg = line; break; case CMD_SEND: for (int i = 0; (scr = reg_get(&line->scriptlets, i)) != NULL; i++) { if (scr->exec != NULL) { scr->exec(line, scr); } } if (trace) { log_hexdump2(line->buffer, line->length, 0, "Send : "); } size = write(sockfd, line->buffer, line->length); if (size < 0) { log_errno("Error writing to socket at line %d\n", lineno); err = -1; } break; case CMD_EXPECT: line->mask = mem_alloc_c(line->length, "line_mask"); memset(line->mask, 0xff, line->length); for (int i = 0; (scr = reg_get(&line->scriptlets, i)) != NULL; i++) { if (scr->exec != NULL) { scr->exec(line, scr); } } err = compare_packet(sockfd, line->buffer, line->mask, line->length, lineno); mem_free(line->mask); line->mask = NULL; if (err != 0) { if (errmsg != NULL) { log_error("> %d: %s -> %d\n", lineno, errmsg->buffer, err); } return err; } break; case CMD_INIT: send_sync(sockfd); err = compare_packet(sockfd, line->buffer, NULL, line->length, lineno); if (err != 0) { if (errmsg != NULL) { log_error("> %d: %s -> %d\n", lineno, errmsg->buffer, err); } return err; } break; } curpos++; } return 0; }
void trigger(void *cvoid, zctx_t * context, void * control) { triggerconfig_t * c = (triggerconfig_t*) cvoid; //set up msgpack stuff zclock_log("watch_port started!"); msgpack_zone mempool; msgpack_zone_init(&mempool, 2048); // TODO char * user_id = "17"; // TODO get broker in somehow char * broker = "tcp://au.ninjablocks.com:5773"; mdcli_t * client = mdcli_new(broker, 1); //VERBOSE triggermemory_t trigger_memory; msgpack_object * addins_obj = parse_msgpack(&mempool, c->addins); if(!parse_addins(addins_obj, &trigger_memory)) { //bad message zclock_log("bad trigger definition"); msgpack_object_print(stdout, *addins_obj); send_sync("bad trigger", control); return; } zclock_log("Creating trigger: target %s, rule_id %s, name %s", c->target_worker, c->rule_id, c->trigger_name); dump_trigger(&trigger_memory); triggerfunction trigger_func; if(!(trigger_func = find_trigger(c->channel, c->trigger_name))) { zclock_log("no trigger found for channel %s, trigger %s", c->channel, c->trigger_name); send_sync("no such trigger", control); return; } void * line = zsocket_new(context, ZMQ_SUB); // what line are we on? // this comes in the addins. char * linesocket = to_linesocket(trigger_memory.line_id); zclock_log("trigger is connecting to listen on %s", linesocket); zsocket_connect(line, linesocket); zsockopt_set_unsubscribe(line, ""); zsockopt_set_subscribe(line, "VALUE"); recv_sync("ping", control); send_sync("pong", control); zmq_pollitem_t items [] = { { line, 0, ZMQ_POLLIN, 0 }, { control, 0, ZMQ_POLLIN, 0 } }; while(1) { // listen on control and line zmq_poll (items, 2, -1); if (items[1].revents & ZMQ_POLLIN) { zclock_log("rule %s received message on control pipe", c->rule_id); // control message // really only expecting DESTROY zmsg_t * msg = zmsg_recv(control); char * str = zmsg_popstr(msg); zmsg_destroy(&msg); if (strcmp("Destroy", str) == 0) { zclock_log("rule %s will quit on request", c->rule_id); free(str); send_sync("ok", control); zclock_log("rule %s quitting on request", c->rule_id); break; } else { zclock_log("unexpected command %s for rule %s", str, c->rule_id); free(str); send_sync("ok", control); } } if (items[0].revents & ZMQ_POLLIN) { // serial update zmsg_t * msg = zmsg_recv(line); zframe_t * cmd = zmsg_pop(msg); if(zframe_streq(cmd, "CHANNEL_CHANGE")) { // TODO // must have been dormant to have gotten this char * new_channel = zmsg_popstr(msg); if(strcmp(c->channel, new_channel) == 0) { // oh, happy day! We're relevant again. // reactivate and start looking at reset levels. zclock_log("line %d: changed channel from %s to %s: trigger coming back to life", trigger_memory.line_id, c->channel, new_channel); zsockopt_set_subscribe(line, "VALUE"); zsockopt_set_unsubscribe(line, "CHANNEL_CHANGE"); } free(new_channel); } else if (zframe_streq(cmd, "VALUE")) { zframe_t * vframe = zmsg_pop(msg); int value; memcpy(&value, zframe_data(vframe), sizeof(int)); char * update_channel = zmsg_popstr(msg); if(strcmp(c->channel, update_channel) != 0) { // channel changed, go dormant // this is legit according to my tests at // https://gist.github.com/2042350 zclock_log("line %d: changed channel from %s to %s: trigger going dormant", trigger_memory.line_id, c->channel, update_channel); zsockopt_set_subscribe(line, "CHANNEL_CHANGE"); zsockopt_set_unsubscribe(line, "VALUE"); } else if(trigger_func(&trigger_memory, value)) { send_trigger(client, c->target_worker, c->rule_id, value, user_id); } free(update_channel); } else { // shouldn't ever happen. zclock_log("shouldn't have received command %s\n", zframe_strdup(cmd)); } zmsg_destroy(&msg); zframe_destroy(&cmd); } } msgpack_zone_destroy(&mempool); }
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req) { uint64_t request; uint32_t prefix[2]; int veclen = req->count; enum workarounds workaround = WORKAROUND_NONE; if(c->has_error) return 0; assert(c != 0); assert(vector != 0); assert(req->count > 0); if(!(flags & XCB_REQUEST_RAW)) { static const char pad[3]; unsigned int i; uint16_t shortlen = 0; size_t longlen = 0; assert(vector[0].iov_len >= 4); /* set the major opcode, and the minor opcode for extensions */ if(req->ext) { const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext); if(!(extension && extension->present)) { _xcb_conn_shutdown(c, XCB_CONN_CLOSED_EXT_NOTSUPPORTED); return 0; } ((uint8_t *) vector[0].iov_base)[0] = extension->major_opcode; ((uint8_t *) vector[0].iov_base)[1] = req->opcode; } else ((uint8_t *) vector[0].iov_base)[0] = req->opcode; /* put together the length field, possibly using BIGREQUESTS */ for(i = 0; i < req->count; ++i) { longlen += vector[i].iov_len; if(!vector[i].iov_base) { vector[i].iov_base = (char *) pad; assert(vector[i].iov_len <= sizeof(pad)); } } assert((longlen & 3) == 0); longlen >>= 2; if(longlen <= c->setup->maximum_request_length) { /* we don't need BIGREQUESTS. */ shortlen = longlen; longlen = 0; } else if(longlen > xcb_get_maximum_request_length(c)) { _xcb_conn_shutdown(c, XCB_CONN_CLOSED_REQ_LEN_EXCEED); return 0; /* server can't take this; maybe need BIGREQUESTS? */ } /* set the length field. */ ((uint16_t *) vector[0].iov_base)[1] = shortlen; if(!shortlen) { prefix[0] = ((uint32_t *) vector[0].iov_base)[0]; prefix[1] = ++longlen; vector[0].iov_base = (uint32_t *) vector[0].iov_base + 1; vector[0].iov_len -= sizeof(uint32_t); --vector, ++veclen; vector[0].iov_base = prefix; vector[0].iov_len = sizeof(prefix); } } flags &= ~XCB_REQUEST_RAW; /* do we need to work around the X server bug described in glx.xml? */ /* XXX: GetFBConfigs won't use BIG-REQUESTS in any sane * configuration, but that should be handled here anyway. */ if(req->ext && !req->isvoid && !strcmp(req->ext->name, "GLX") && ((req->opcode == 17 && ((uint32_t *) vector[0].iov_base)[1] == 0x10004) || req->opcode == 21)) workaround = WORKAROUND_GLX_GET_FB_CONFIGS_BUG; /* get a sequence number and arrange for delivery. */ pthread_mutex_lock(&c->iolock); /* wait for other writing threads to get out of my way. */ while(c->out.writing) pthread_cond_wait(&c->out.cond, &c->iolock); get_socket_back(c); /* send GetInputFocus (sync_req) when 64k-2 requests have been sent without * a reply. */ if(req->isvoid && c->out.request == c->in.request_expected + (1 << 16) - 2) send_sync(c); /* Also send sync_req (could use NoOp) at 32-bit wrap to avoid having * applications see sequence 0 as that is used to indicate * an error in sending the request */ if((unsigned int) (c->out.request + 1) == 0) send_sync(c); /* The above send_sync calls could drop the I/O lock, but this * thread will still exclude any other thread that tries to write, * so the sequence number postconditions still hold. */ send_request(c, req->isvoid, workaround, flags, vector, veclen); request = c->has_error ? 0 : c->out.request; pthread_mutex_unlock(&c->iolock); return request; }
int main(int argc, char *argv[]) { int rv = -1; const char *device = NULL; const char *tsocket = NULL; const char *scriptname = NULL; // wait for socket if not there right away? int dowait = 0; terminal_init(); int i=1; while(i<argc && argv[i][0]=='-' && argv[i][1] != 0) { switch(argv[i][1]) { case '?': assert_single_char(argv[i]); usage(EXIT_SUCCESS); /* usage() exits already */ break; case 'd': assert_single_char(argv[i]); if (i < argc-1) { i++; device = argv[i]; log_info("main: device = %s\n", device); } else { log_error("-d requires <device> parameter\n"); exit(1); } break; case 'T': assert_single_char(argv[i]); if (i < argc-1) { i++; tsocket = argv[i]; log_info("main: tools socket = %s\n", tsocket); } else { log_error("-T requires <socket> parameter\n"); exit(1); } break; case 'v': set_verbose(1); break; case 't': trace = 1; break; case 'w': dowait = 1; break; default: log_error("Unknown command line option %s\n", argv[i]); usage(1); break; } i++; } // next parameter is the script name if (i >= argc) { log_error("Script name parameter missing!\n"); return -1; } scriptname = argv[i]; i++; registry_t *script = load_script_from_file(scriptname); if (script != NULL) { int sockfd = socket_open(device, dowait); int toolsfd = -1; if (tsocket) { toolsfd = socket_open(tsocket, 1); send_sync(toolsfd); } if (sockfd >= 0) { rv = execute_script(sockfd, toolsfd, script); close(sockfd); } if (toolsfd >= 0) { close(toolsfd); } } return rv; }
/** * returns the status of the execution * 0 = normal end * 1 = expect mismatch */ int execute_script(int sockfd, int toolsfd, registry_t *script) { // current "pc" pointer to script line int curpos = 0; line_t *line = NULL; int lineno = 0; int err = 0; ssize_t size = 0; line_t *errmsg = NULL; scriptlet_t *scr = NULL; // guaranteed to be valid; toolsfd may be not set (<0) int curfd = sockfd; while ( (err == 0) && (line = reg_get(script, curpos)) != NULL) { lineno = line->num; switch (line->cmd) { case CMD_COMMENT: if (!trace) { break; } // fall-through case CMD_MESSAGE: log_info("> %s\n", line->buffer); break; case CMD_ERRMSG: errmsg = line; break; case CMD_SEND: for (int i = 0; (scr = reg_get(&line->scriptlets, i)) != NULL; i++) { if (scr->exec != NULL) { scr->exec(line, scr); } } if (trace) { log_hexdump2(line->buffer, line->length, 0, "Send : "); } size = write(curfd, line->buffer, line->length); if (size < 0) { log_errno("Error writing to socket at line %d\n", lineno); err = -1; } break; case CMD_EXPECT: line->mask = mem_alloc_c(line->length, "line_mask"); memset(line->mask, 0xff, line->length); for (int i = 0; (scr = reg_get(&line->scriptlets, i)) != NULL; i++) { if (scr->exec != NULL) { scr->exec(line, scr); } } err = compare_packet(curfd, line->buffer, line->mask, line->length, lineno); mem_free(line->mask); line->mask = NULL; if (err != 0) { if (errmsg != NULL) { log_error("> %d: %s -> %d\n", lineno, errmsg->buffer, err); } return 1; } break; case CMD_INIT: send_sync(curfd); err = compare_packet(curfd, line->buffer, NULL, line->length, lineno); if (err != 0) { if (errmsg != NULL) { log_error("> %d: %s -> %d\n", lineno, errmsg->buffer, err); } return 1; } break; case CMD_CHANNEL: if ((!strcmp("tools", line->buffer)) && toolsfd >= 0) { curfd = toolsfd; } else if ((!strcmp("device", line->buffer)) && sockfd >= 0) { curfd = sockfd; } else { log_error("> %d: -> unknown channel name %s\n", lineno, line->buffer); return 1; } break; } curpos++; } return 0; }
void send_belfox(char *msg) { uint8_t repeat=BELFOX_REPEAT; uint8_t len=strnlen(msg,BELFOX_LEN+2)-1; // assert if length incorrect if (len != BELFOX_LEN) return; LED_ON(); #if defined (HAS_IRRX) || defined (HAS_IRTX) // Block IR_Reception cli(); #endif #ifdef USE_RF_MODE change_RF_mode(RF_mode_slow); #else #ifdef HAS_MORITZ uint8_t restore_moritz = 0; if(moritz_on) { restore_moritz = 1; moritz_on = 0; set_txreport("21"); } #endif if(!cc_on) set_ccon(); #endif ccTX(); // Enable TX do { send_sync(); // sync for(int i = 1; i <= BELFOX_LEN; i++) // loop input, for example 'L111001100110' send_bit(msg[i] == '1'); CC1100_OUT_PORT &= ~_BV(CC1100_OUT_PIN); // final low to complete last bit my_delay_ms(BELFOX_PAUSE); // pause } while(--repeat > 0); if(TX_REPORT) { // Enable RX ccRX(); } else { ccStrobe(CC1100_SIDLE); } #if defined (HAS_IRRX) || defined (HAS_IRTX) // Activate IR_Reception sei(); #endif #ifdef USE_RF_MODE restore_RF_mode(); #else #ifdef HAS_MORITZ if(restore_moritz) rf_moritz_init(); #endif #endif LED_OFF(); }
void parent_handshake(void*pipe) { send_sync("ping", pipe); recv_sync("pong", pipe); }
void child_handshake(void*pipe) { recv_sync("ping", pipe); send_sync("pong", pipe); }