int DLGSM::PT_send_recv_confirm(struct pt *pt, char *ret, char *cmd, char *conf, int tout) { static uint32_t ts,startts; static struct pt linerecv_pt; PT_BEGIN(pt); *ret = 0; ts = millis(); GSM_send(cmd); PT_WAIT_UNTIL(pt, _gsmserial.available() || (millis() - ts) > tout); if (!_gsmserial.available()) { *ret = 0; PT_EXIT(pt); } ts = millis(); startts = millis(); _gsm_wline = 1; while (_gsmserial.available() || (millis() - startts) < tout) { PT_WAIT_THREAD(pt, PT_recvline(&linerecv_pt, ret, _gsm_buff, _gsm_buffsize, tout, 1)); ts = millis(); if (*ret == 0) _tout_cnt++; if (conf != NULL && strstr(_gsm_buff, conf) != NULL) { *ret = 1; PT_EXIT(pt); } else if (conf != NULL && (strstr(_gsm_buff, "ERROR") != NULL || strstr(_gsm_buff, "FAIL") != NULL)) { *ret = 2; _error_cnt++; PT_EXIT(pt); } else if (conf != NULL) *ret = 0; } _gsm_wline = 0; PT_END(pt); }
int DLGSM::PT_recvline(struct pt *pt, char *ret, char *ptr, int len, int tout, char process) { int a = 0, k = 0; char cchar = 0; static uint32_t ts = 0; PT_BEGIN(pt); ts = millis(); gsm_pt_i = 0; *ret = 0; while (gsm_pt_i < len) { PT_WAIT_UNTIL(pt, _gsmserial.available() > 0 || (millis() - ts) > tout); ts = millis(); a = _gsmserial.available(); if (a > 0) { for(k=0; cchar != '\n' && k<a && gsm_pt_i < len;k++) { cchar = _gsmserial.read(); ptr[gsm_pt_i] = cchar; gsm_pt_i++; } if (cchar == '\n') { ptr[gsm_pt_i] = 0; if (gsm_pt_i > 2) { if (_DEBUG) { Serial.print("Line: "); Serial.print(ptr); } if (process) GSM_process_line(NULL); if (_gsm_callback) _gsm_callback(ptr, gsm_pt_i); } *ret = gsm_pt_i; PT_EXIT(pt); } _tout_cnt = 0; } else if (_gsm_wline) { ptr[gsm_pt_i] = 0; if (_DEBUG) { Serial.print("Line: "); Serial.print(ptr); } if (process) GSM_process_line(NULL); if (_gsm_callback) _gsm_callback(ptr, gsm_pt_i); *ret = gsm_pt_i; _tout_cnt++; PT_EXIT(pt); } } PT_END(pt); }
int DLGSM::PT_recv(struct pt *pt, char *ret, char *conf, int tout, char process) { static uint32_t ts, startts; static struct pt linerecv_pt; PT_BEGIN(pt); ts = millis(); *ret = 0; PT_WAIT_UNTIL(pt, _gsmserial.available() || (millis() - ts) > tout); ts = millis(); if (!_gsmserial.available()) { *ret = 0; PT_EXIT(pt); } startts = millis(); _gsm_wline = 1; while (_gsmserial.available() || (millis() - startts) < tout) { PT_WAIT_THREAD(pt, PT_recvline(&linerecv_pt, ret, _gsm_buff, _gsm_buffsize, tout, process)); if (conf != NULL && strstr(_gsm_buff, conf) != NULL) *ret = 1; else if (conf != NULL) *ret = 0; } _gsm_wline = 0; PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); petsciiconv_topetscii(s->filename, sizeof(s->filename)); s->fd = cfs_open(s->filename, CFS_READ); petsciiconv_toascii(s->filename, sizeof(s->filename)); if(s->fd < 0) { strcpy(s->filename, "notfound.html"); s->fd = cfs_open(s->filename, CFS_READ); petsciiconv_toascii(s->filename, sizeof(s->filename)); if(s->fd < 0) { PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); PT_WAIT_THREAD(&s->outputpt, send_string(s, "not found")); uip_close(); webserver_log_file(&uip_conn->ripaddr, "404 (no notfound.html)"); PT_EXIT(&s->outputpt); } PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); webserver_log_file(&uip_conn->ripaddr, "404 - notfound.html"); } else { PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); } PT_WAIT_THREAD(&s->outputpt, send_file(s)); cfs_close(s->fd); s->fd = -1; PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
int DLGSM::PT_SMS_process(struct pt *pt, char *ret, SMS_t *sms) { static struct pt child_pt; PT_BEGIN(pt); *ret = -1; if (!curr_sms.index) PT_EXIT(pt); if (_DEBUG) { Serial.print("index: "); Serial.println(curr_sms.index); Serial.print("number: "); Serial.println(curr_sms.number); Serial.print("message: "); Serial.println(curr_sms.message); } if (strncmp(sms->message, "RE", 2) == 0) { // Reboot *ret = GSM_EVENT_REBOOT; } else if (strncmp(sms->message, "ST", 2) == 0) { // Send HTTP status *ret = GSM_EVENT_STATUS_REQ; } else if (strncmp(sms->message, "GA", 2) == 0) { // Get all readings *ret = GSM_EVENT_GET_ALL_READINGS; } else if (strncmp(sms->message, "I ", 2) == 0) { // Individual reading *ret = GSM_EVENT_GET_READING; } else if (strncmp(sms->message, "INFO", 4) == 0) { // System info *ret = GSM_EVENT_SYSINFO; } else if (strncmp(sms->message, "UP", 2) == 0) { // Uptime *ret = GSM_EVENT_UPTIME; } if (_DEBUG) Serial.println(*ret, DEC); PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); s->fd = cfs_open(s->filename, CFS_READ); if(s->fd < 0) { s->fd = cfs_open("404.html", CFS_READ); if(s->fd < 0) { uip_abort(); PT_EXIT(&s->outputpt); } PT_WAIT_THREAD(&s->outputpt, send_headers(s, "HTTP/1.0 404 Not found\r\n")); PT_WAIT_THREAD(&s->outputpt, send_file(s)); } else { PT_WAIT_THREAD(&s->outputpt, send_headers(s, "HTTP/1.0 200 OK\r\n")); PT_WAIT_THREAD(&s->outputpt, send_file(s)); cfs_close(s->fd); } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
int DLGSM::PT_GPRS_connect(struct pt *pt, char *ret, char *server, short port, bool proto) { char r = 0; char shortbuff[100]; static struct pt child_pt; PT_BEGIN(pt); if (CONN_get_flag(CONN_CONNECTED)) { if (CONN_get_flag(CONN_SENDING)) PT_WAIT_THREAD(pt, PT_GPRS_send_end(&child_pt, &r)); PT_WAIT_THREAD(pt, PT_GPRS_close(&child_pt, &r)); } if (proto) get_from_flash(&(gsm_string_table[1]), _gsm_buff); else get_from_flash(&(gsm_string_table[2]), _gsm_buff); sprintf(shortbuff, "%s\",\"%d\"\r\n", server, port); strcat(_gsm_buff, shortbuff); PT_WAIT_THREAD(pt, PT_send_recv_confirm(&child_pt, &r, _gsm_buff, "CONNECT", 30000)); if (r != 1) { PT_EXIT(pt); } PT_WAIT_THREAD(pt, PT_GPRS_check_conn_state(&child_pt, &r)); if (r == GPRSS_CONNECT_OK) *ret = 1; else *ret = 0; PT_END(pt); }
static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); s->script = NULL; s->script = httpd_simple_get_script(&s->filename[1]); if(s->script == NULL) { strncpy(s->filename, "/notfound.html", sizeof(s->filename)); PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); PT_WAIT_THREAD(&s->outputpt, send_string(s, NOT_FOUND)); uip_close(); webserver_log_file(&uip_conn->ripaddr, "404 - not found"); PT_EXIT(&s->outputpt); } else { PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); PT_WAIT_THREAD(&s->outputpt, s->script(s)); } s->script = NULL; PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(subscribe_pt(struct pt* pt, struct mqtt_connection* conn)) { PT_BEGIN(pt); DBG("MQTT - Sending subscribe message! topic %s topic_length %i\r\n", conn->out_packet.topic, conn->out_packet.topic_length); DBG("MQTT - Buffer space is %i \r\n", &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_SUBSCRIBE | MQTT_FHDR_QOS_LEVEL_1; conn->out_packet.remaining_length = MQTT_MID_SIZE + MQTT_STRING_LEN_SIZE + conn->out_packet.topic_length + MQTT_QOS_SIZE; encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); printf("MQTT - Error, remaining length > 4 bytes\r\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); /* Write Variable Header */ PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); /* Write Payload */ PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.topic, conn->out_packet.topic_length); PT_MQTT_WRITE_BYTE(conn, conn->out_packet.qos); /* Send out buffer */ send_out_buffer(conn); /* Wait for SUBACK. */ reset_packet(&conn->in_packet); do { PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK); } while(conn->out_packet.qos_state != MQTT_QOS_STATE_GOT_ACK); reset_packet(&conn->in_packet); /* This is clear after the entire transaction is complete */ conn->out_queue_full = 0; DBG("MQTT - Done in send_subscribe!\r\n"); PT_END(pt); }
int DLGSM::PT_GSM_event_handler(struct pt *pt, char *ret) { char i = 0; static char iret; static struct pt child_pt; static int n = 0; PT_BEGIN(pt); PT_YIELD_UNTIL(pt, _gsmserial.available() > 1); // +CMTI: "SM",1 while (_gsmserial.available()) { PT_WAIT_THREAD(pt, PT_recvline(&child_pt, &iret, _gsm_buff, _gsm_buffsize, 1000, 1)); if (iret > 0) { // Call arriving, hang up? if (_gsm_buff[0] == 'R') { sprintf(_gsm_buff, "ATH\r\n"); PT_WAIT_THREAD(pt, PT_send_recv_confirm(&child_pt, &iret, _gsm_buff, "OK", 5000)); *ret = GSM_EVENT_STATUS_REQ; PT_EXIT(pt); } else if (_gsm_buff[0] == '+') { if (_gsm_buff[3] == 'T' && _gsm_buff[4] == 'I') { n = atoi((char *)(_gsm_buff+12)); PT_WAIT_THREAD(pt, PT_SMS_read(&child_pt,&iret,n)); iret = 0; PT_WAIT_THREAD(pt, PT_SMS_process(&child_pt, &iret, &curr_sms)); PT_WAIT_THREAD(pt, PT_SMS_delete(&child_pt, n)); *ret = iret; PT_EXIT(pt); } } else { GSM_process_line(NULL); } } } PT_END(pt); }
int DLGSM::PT_GPRS_check_conn_state(struct pt *pt, char *ret) { static struct pt child_pt; static uint8_t k; char iret; char d[15]; PT_BEGIN(pt); get_from_flash(&(gsm_string_table[5]), _gsm_buff); *ret = 0; k = 0; PT_WAIT_THREAD(pt, PT_send_recv_confirm(&child_pt, ret, _gsm_buff, "STATE:", 20000)); if (strcmp_P(_gsm_buff, PSTR("STATE:")) >= 0) { while (k < GPRSS_LEN) { if (strcmp_flash(_gsm_buff+7, &(gprs_state_table[k]), d) == 0) { *ret = k; if (k == GPRSS_IP_INITIAL || k == GPRSS_IP_START || k == GPRSS_IP_CONFIG) { // Reinitialize GPRS PT_WAIT_WHILE(pt, CONN_get_flag(CONN_NETWORK) == 0); PT_WAIT_THREAD(pt, PT_GSM_init(&child_pt, &iret)); PT_WAIT_WHILE(pt, CONN_get_flag(CONN_GPRS_NET) == 0); PT_WAIT_THREAD(pt, PT_GPRS_init(&child_pt, &iret)); } else if (k == GPRSS_IP_GPRSACT) { // Just need to query the local IP... get_from_flash(&(gprs_init_string_table[9]), _gsm_buff); PT_WAIT_THREAD(pt, PT_send_recv(&child_pt, &iret, _gsm_buff, 1000)); } else if (k == GPRSS_CONNECT_OK) { CONN_set_flag(CONN_CONNECTED, 1); } else if (k == GPRSS_TCP_CLOSED || k == GPRSS_UDP_CLOSED) { CONN_set_flag(CONN_CONNECTED, 0); } else if (k == GPRSS_PDP_DEACT) { // Reinitialize GPRS PT_WAIT_WHILE(pt, CONN_get_flag(CONN_NETWORK) == 0); PT_WAIT_THREAD(pt, PT_GSM_init(&child_pt, &iret)); PT_WAIT_WHILE(pt, CONN_get_flag(CONN_GPRS_NET) == 0); PT_WAIT_THREAD(pt, PT_GPRS_init(&child_pt, &iret)); } *ret = k; PT_EXIT(pt); } k++; } } else { PT_RESTART(pt); } *ret = -1; PT_END(pt); }
static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); #if DEBUGLOGIC strcpy_P(s->filename,PSTR("/x")); #endif #if FIND_THE_SCRIPT s->script = httpd_simple_get_script(&s->filename[1]); if(s->script == NULL) { printf_P(PSTR("not found!")); strcpy_P(s->filename, PSTR("/notfound.html")); PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); PT_WAIT_THREAD(&s->outputpt, send_string_P(s, NOT_FOUND)); uip_close(); PT_EXIT(&s->outputpt); } else { #else s->script = generate_routes; if (1) { #endif PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); PT_WAIT_THREAD(&s->outputpt, s->script(s)); } s->script = NULL; PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); } /*---------------------------------------------------------------------------*/ static void handle_connection(struct httpd_state *s) { #if DEBUGLOGIC handle_output(s); #else handle_input(s); if(s->state == STATE_OUTPUT) { handle_output(s); } #endif }
static PT_THREAD(I2C_Write_Buf(struct pt *pt,unsigned char *buf,unsigned char len))//дочерний поток записи буфера I2C { static volatile unsigned char write_byte_counter,bit_counter,write_byte; PT_BEGIN(pt); MDE=1;//передача write_byte_counter=0; while(write_byte_counter<len) //цикл передачи буфера { // bit_counter=0; write_byte=buf[write_byte_counter]; write_byte_counter++; MCO=0; PT_YIELD(pt);//дадим другим процессам время for(bit_counter=0;bit_counter<8;bit_counter++) { write_byte=write_byte<<1;//>>1; //??? MDO=CY; MCO=1; PT_YIELD(pt);//дадим другим процессам время MCO=0; // PT_YIELD(pt);//дадим другим процессам время } MDE=0;//прием MCO=0; PT_YIELD(pt);//дадим другим процессам время MCO=1; PT_YIELD(pt);//дадим другим процессам время MCO=0; MDE=1;//передача if(MDI) //NACK { ERROR_I2C=1;//случилась ошибка PT_EXIT(pt); } } ERROR_I2C=0; PT_END(pt); }
static PT_THREAD (protothread3(struct pt *pt)) { PT_BEGIN(pt); while(1) { // send the prompt via DMA to serial sprintf(PT_send_buffer,"cmd>"); // by spawning a print thread PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); //spawn a thread to handle terminal input // the input thread waits for input // -- BUT does NOT block other threads // string is returned in "PT_term_buffer" PT_SPAWN(pt, &pt_input, PT_GetSerialBuffer(&pt_input) ); // returns when the thead dies // in this case, when <enter> is pushed // now parse the string sscanf(PT_term_buffer, "%s %d", cmd, &value); if (cmd[0]=='t' && cmd[1]=='1') { wait_t1 = value ;} // set the blink time MILLIsec if (cmd[0]=='t' && cmd[1]=='4') { wait_t2 = value ;} // set the blink time MICROsec if (cmd[0] == 'g' && cmd[1]=='1') {cntl_blink = 1 ;} // make it blink using YIELD if (cmd[0] == 's' && cmd[1]=='1') {cntl_blink = 0 ;} // make it stop if (cmd[0] == 'g' && cmd[1]=='4') {run_t4 = 1 ;} // make it blink using scheduler if (cmd[0] == 's' && cmd[1]=='4') {run_t4 = 0 ;} // make it stop using scheduler if (cmd[0] == 'k') {PT_EXIT(pt);} // kill this input thread (see also MAIN) // scheduler control if (cmd[0] == 'p' && cmd[1]=='1') { t1_rate = value ;} if (cmd[0] == 'p' && cmd[1]=='3') { t3_rate = value ;} if (cmd[0] == 'p' && cmd[1]=='4') { t4_rate = value ;} if (cmd[0] == 'z') printf("%d\t%d\n\r", PT_GET_TIME(), sys_time_seconds); // never exit while } // END WHILE(1) PT_END(pt); } // thread 3
/*---------------------------------------------------------------------------*/ static int parse_header_byte(struct http_socket *s, char c) { static int i; static char status_code[3]; static char ending[4]; PT_BEGIN(&s->headerpt); /* Zero initialize static char arrays */ memset(status_code, 0, sizeof(status_code)); memset(ending, 0, sizeof(ending)); /* Skip the HTTP response */ while(c != ' ') { PT_YIELD(&s->headerpt); } /* Skip the space */ PT_YIELD(&s->headerpt); /* Read three bytes of HTTP status */ for(i = 0; i < 3; i++) { status_code[i] = c; PT_YIELD(&s->headerpt); } if(memcmp(status_code, "404", 3) == 0) { PRINTF("File not found\n"); call_callback(s, HTTP_SOCKET_404, NULL, 0); while(1) { PT_YIELD(&s->headerpt); } } else if(memcmp(status_code, "301", 3) == 0 || memcmp(status_code, "302", 3) == 0) { PRINTF("File moved (not handled)\n"); while(1) { PT_YIELD(&s->headerpt); } } else if(memcmp(status_code, "200", 3) == 0) { /* Skip headers until data */ do { /* Read bytes until first \r */ do { PT_YIELD(&s->headerpt); } while(c != '\r'); /* Check for \r\n\r\n, otherwise continue looping */ i = 0; while((c == '\r' || c == '\n') && i < sizeof(ending)) { ending[i] = c; i++; PT_YIELD(&s->headerpt); } } while(i != 4 && memcmp(ending, "\r\n\r\n", 4) != 0); /* All headers skipped, now read data */ /* Should exit the pt here to indicate that all headers have been read */ PT_EXIT(&s->headerpt); } else { while(1) { PT_YIELD(&s->headerpt); } } PT_END(&s->headerpt); }
/*---------------------------------------------------------------------------*/ static int parse_header_byte(struct http_socket *s, char c) { PT_BEGIN(&s->headerpt); memset(&s->header, -1, sizeof(s->header)); /* Skip the HTTP response */ while(c != ' ') { PT_YIELD(&s->headerpt); } /* Skip the space */ PT_YIELD(&s->headerpt); /* Read three characters of HTTP status and convert to BCD */ s->header.status_code = 0; for(s->header_chars = 0; s->header_chars < 3; s->header_chars++) { s->header.status_code = s->header.status_code << 4 | (c - '0'); PT_YIELD(&s->headerpt); } if(s->header.status_code == 0x200 || s->header.status_code == 0x206) { /* Read headers until data */ while(1) { /* Skip characters until end of line */ do { while(c != '\r') { s->header_chars++; PT_YIELD(&s->headerpt); } s->header_chars++; PT_YIELD(&s->headerpt); } while(c != '\n'); s->header_chars--; PT_YIELD(&s->headerpt); if(s->header_chars == 0) { /* This was an empty line, i.e. the end of headers */ break; } /* Start of line */ s->header_chars = 0; /* Read header field */ while(c != ' ' && c != '\t' && c != ':' && c != '\r' && s->header_chars < sizeof(s->header_field) - 1) { s->header_field[s->header_chars++] = c; PT_YIELD(&s->headerpt); } s->header_field[s->header_chars] = '\0'; /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c == ':') { /* Skip the colon */ s->header_chars++; PT_YIELD(&s->headerpt); /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(!strcmp(s->header_field, "Content-Length")) { s->header.content_length = 0; while(isdigit((int)c)) { s->header.content_length = s->header.content_length * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } } else if(!strcmp(s->header_field, "Content-Range")) { /* Skip the bytes-unit token */ while(c != ' ' && c != '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } s->header.content_range.first_byte_pos = 0; while(isdigit((int)c)) { s->header.content_range.first_byte_pos = s->header.content_range.first_byte_pos * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c == '-') { /* Skip the dash */ s->header_chars++; PT_YIELD(&s->headerpt); /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } s->header.content_range.last_byte_pos = 0; while(isdigit((int)c)) { s->header.content_range.last_byte_pos = s->header.content_range.last_byte_pos * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c == '/') { /* Skip the slash */ s->header_chars++; PT_YIELD(&s->headerpt); /* Skip linear white spaces */ while(c == ' ' || c == '\t') { s->header_chars++; PT_YIELD(&s->headerpt); } if(c != '*') { s->header.content_range.instance_length = 0; while(isdigit((int)c)) { s->header.content_range.instance_length = s->header.content_range.instance_length * 10 + c - '0'; s->header_chars++; PT_YIELD(&s->headerpt); } } } } } } } /* All headers read, now read data */ call_callback(s, HTTP_SOCKET_HEADER, (void *)&s->header, sizeof(s->header)); /* Should exit the pt here to indicate that all headers have been read */ PT_EXIT(&s->headerpt); } else { if(s->header.status_code == 0x404) { puts("File not found"); } else if(s->header.status_code == 0x301 || s->header.status_code == 0x302) { puts("File moved (not handled)"); } call_callback(s, HTTP_SOCKET_ERR, (void *)&s->header, sizeof(s->header)); tcp_socket_close(&s->s); removesocket(s); PT_EXIT(&s->headerpt); } PT_END(&s->headerpt); }
/*---------------------------------------------------------------------------*/ static int input_byte(uint8_t byte) { int crc; if(timer_expired(&rxstate.timer)) { restart_input(); } PT_BEGIN(&rxstate.pt); /* The first incoming byte is the length of the packet. */ rxstate.receiving = 1; rxstate.len = byte; if(byte == 0) { #if DEBUG printf("Bad len 0, state %d rxbytes %d\n", state(), read_rxbytes()); #endif /* DEBUG */ flushrx(); PT_EXIT(&rxstate.pt); } timer_set(&rxstate.timer, PACKET_LIFETIME); for(rxstate.ptr = 0; rxstate.ptr < rxstate.len; rxstate.ptr++) { /* Wait for the next data byte to be received. */ PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; } /* Receive two more bytes from the FIFO: the RSSI value and the LQI/CRC */ PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; rxstate.ptr++; PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; crc = (byte & 0x80); rxstate.ptr++; if(crc == 0) { #if DEBUG printf("bad crc\n"); #endif /* DEBUG */ flushrx(); } else if(packet_rx_len > 0) { #if DEBUG printf("Packet in the buffer (%d), dropping %d bytes\n", packet_rx_len, rxstate.len); #endif /* DEBUG */ flushrx(); process_poll(&cc1101_process); } else if(rxstate.len < ACK_LEN) { /* Drop packets that are way too small: less than ACK_LEN (3) bytes long. */ #if DEBUG printf("!"); #endif /* DEBUG */ } else { /* Read out the first three bytes to determine if we should send an ACK or not. */ /* Send a link-layer ACK before reading the full packet. */ if(rxstate.len >= ACK_LEN) { /* Try to parse the incoming frame as a 802.15.4 header. */ frame802154_t info154; if(frame802154_parse(rxstate.buf, rxstate.len, &info154) != 0) { /* XXX Potential optimization here: we could check if the frame is destined for us, or for the broadcast address and discard the packet if it isn't for us. */ if(1) { /* For dataframes that has the ACK request bit set and that is destined for us, we send an ack. */ if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && rimeaddr_cmp((rimeaddr_t *)&info154.dest_addr, &rimeaddr_node_addr)) { send_ack(info154.seq); /* Make sure that we don't put the radio in the IDLE state before the ACK has been fully transmitted. */ BUSYWAIT_UNTIL((state() != CC1101_STATE_TX), RTIMER_SECOND / 10); ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); if(state() == CC1101_STATE_TX) { #if DEBUG printf("didn't end ack tx (in %d, txbytes %d)\n", state(), txbytes()); #endif /* DEBUG */ check_txfifo(); flushrx(); } } memcpy((void *)packet_rx, rxstate.buf, rxstate.len + AUX_LEN); packet_rx_len = rxstate.len + AUX_LEN; /* including AUX */ process_poll(&cc1101_process); #if DEBUG printf("#"); #endif /* DEBUG */ } } } } rxstate.receiving = 0; PT_END(&rxstate.pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(connect_pt(struct pt* pt, struct mqtt_connection* conn)) { PT_BEGIN(pt); DBG("MQTT - Sending CONNECT message...\r\n"); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_CONNECT; conn->out_packet.remaining_length = 0; conn->out_packet.remaining_length += MQTT_connect_vhdr_flags_SIZE; conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->client_id); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.username); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.password); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.topic); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.message); encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); printf("MQTT - Error, remaining length > 4 bytes\r\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); PT_MQTT_WRITE_BYTE(conn, 0); PT_MQTT_WRITE_BYTE(conn, 6); PT_MQTT_WRITE_BYTES(conn, (uint8_t*)MQTT_PROTOCOL_NAME, 6); PT_MQTT_WRITE_BYTE(conn, MQTT_PROTOCOL_VERSION); PT_MQTT_WRITE_BYTE(conn, conn->connect_vhdr_flags); PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive & 0x00FF)); PT_MQTT_WRITE_BYTE(conn, conn->client_id.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->client_id.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->client_id.string, conn->client_id.length); if(conn->connect_vhdr_flags & MQTT_VHDR_WILL_FLAG) { PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->will.topic.string, conn->will.topic.length); PT_MQTT_WRITE_BYTE(conn, conn->will.message.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->will.message.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->will.message.string, conn->will.message.length); DBG("MQTT - Setting will topic to '%s' %i bytes and message to '%s' %i bytes\r\n", conn->will.topic.string, conn->will.topic.length, conn->will.message.string, conn->will.message.length); } if(conn->connect_vhdr_flags & MQTT_VHDR_USERNAME_FLAG) { DBG("MQTT - Setting username\r\n"); PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->credentials.username.string, conn->credentials.username.length); } if(conn->connect_vhdr_flags & MQTT_VHDR_PASSWORD_FLAG) { DBG("MQTT - Setting password\r\n"); PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, conn->credentials.password.string, conn->credentials.password.length); } /* Send out buffer */ send_out_buffer(conn); conn->state = MQTT_CONN_STATE_CONNECTING_TO_BROKER; /* Wait for CONNACK */ reset_packet(&conn->in_packet); do { PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK); } while(conn->out_packet.qos_state != MQTT_QOS_STATE_GOT_ACK); reset_packet(&conn->in_packet); DBG("MQTT - Done sending CONNECT since we got CONNACK!\r\n"); #if DEBUG_MQTT == 1 DBG("MQTT - Sending CONNECT message: \r\n"); uint16_t i; for( i = 0; i < (conn->out_buffer_ptr - conn->out_buffer); i++ ) { DBG( "%02X ", conn->out_buffer[i] ); } DBG("\r\n"); #endif PT_END(pt); }
int main(int argc, char **argv) { afs_int32 code; afs_uint32 myHost; struct hostent *th; char hostname[64]; struct rx_service *tservice; struct rx_securityClass **securityClasses; afs_int32 numClasses; int lwps = 3; char clones[MAXHOSTSPERCELL]; afs_uint32 host = htonl(INADDR_ANY); struct cmd_syndesc *opts; struct cmd_item *list; char *pr_dbaseName; char *configDir; char *logFile; char *whoami = "ptserver"; char *auditFileName = NULL; char *interface = NULL; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGABRT, &nsa, NULL); sigaction(SIGSEGV, &nsa, NULL); #endif osi_audit_init(); osi_audit(PTS_StartEvent, 0, AUD_END); /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } pr_dbaseName = strdup(AFSDIR_SERVER_PRDB_FILEPATH); configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH); logFile = strdup(AFSDIR_SERVER_PTLOG_FILEPATH); #if defined(SUPERGROUPS) /* make sure the structures for database records are the same size */ if ((sizeof(struct prentry) != ENTRYSIZE) || (sizeof(struct prentryg) != ENTRYSIZE)) { fprintf(stderr, "The structures for the database records are different" " sizes\n" "struct prentry = %" AFS_SIZET_FMT "\n" "struct prentryg = %" AFS_SIZET_FMT "\n" "ENTRYSIZE = %d\n", sizeof(struct prentry), sizeof(struct prentryg), ENTRYSIZE); PT_EXIT(1); } #endif cmd_DisableAbbreviations(); cmd_DisablePositionalCommands(); opts = cmd_CreateSyntax(NULL, NULL, NULL, NULL); /* ptserver specific options */ cmd_AddParmAtOffset(opts, OPT_database, "-database", CMD_SINGLE, CMD_OPTIONAL, "database file"); cmd_AddParmAlias(opts, OPT_database, "db"); cmd_AddParmAtOffset(opts, OPT_access, "-default_access", CMD_SINGLE, CMD_OPTIONAL, "default access flags for new entries"); #if defined(SUPERGROUPS) cmd_AddParmAtOffset(opts, OPT_groupdepth, "-groupdepth", CMD_SINGLE, CMD_OPTIONAL, "max search depth for supergroups"); cmd_AddParmAlias(opts, OPT_groupdepth, "depth"); #endif cmd_AddParmAtOffset(opts, OPT_restricted, "-restricted", CMD_FLAG, CMD_OPTIONAL, "enable restricted mode"); /* general server options */ cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE, CMD_OPTIONAL, "location of audit log"); cmd_AddParmAtOffset(opts, OPT_auditiface, "-audit-interface", CMD_SINGLE, CMD_OPTIONAL, "interface to use for audit logging"); cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE, CMD_OPTIONAL, "configuration location"); cmd_AddParmAtOffset(opts, OPT_debug, "-d", CMD_SINGLE, CMD_OPTIONAL, "debug level"); cmd_AddParmAtOffset(opts, OPT_logfile, "-logfile", CMD_SINGLE, CMD_OPTIONAL, "location of logfile"); cmd_AddParmAtOffset(opts, OPT_threads, "-p", CMD_SINGLE, CMD_OPTIONAL, "number of threads"); #if !defined(AFS_NT40_ENV) cmd_AddParmAtOffset(opts, OPT_syslog, "-syslog", CMD_SINGLE_OR_FLAG, CMD_OPTIONAL, "log to syslog"); #endif /* rx options */ cmd_AddParmAtOffset(opts, OPT_peer, "-enable_peer_stats", CMD_FLAG, CMD_OPTIONAL, "enable RX transport statistics"); cmd_AddParmAtOffset(opts, OPT_process, "-enable_process_stats", CMD_FLAG, CMD_OPTIONAL, "enable RX RPC statistics"); cmd_AddParmAtOffset(opts, OPT_rxbind, "-rxbind", CMD_FLAG, CMD_OPTIONAL, "bind only to the primary interface"); cmd_AddParmAtOffset(opts, OPT_rxmaxmtu, "-rxmaxmtu", CMD_SINGLE, CMD_OPTIONAL, "maximum MTU for RX"); /* rxkad options */ cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals", CMD_FLAG, CMD_OPTIONAL, "permit Kerberos 5 principals with dots"); code = cmd_Parse(argc, argv, &opts); if (code) PT_EXIT(1); cmd_OptionAsString(opts, OPT_config, &configDir); cmd_OpenConfigFile(AFSDIR_SERVER_CONFIG_FILE_FILEPATH); cmd_SetCommandName("ptserver"); if (cmd_OptionAsList(opts, OPT_access, &list) == 0) { prp_user_default = prp_access_mask(list->data); if (list->next == NULL || list->next->data == NULL) { fprintf(stderr, "Missing second argument for -default_access\n"); PT_EXIT(1); } prp_group_default = prp_access_mask(list->next->data); } #if defined(SUPERGROUPS) cmd_OptionAsInt(opts, OPT_groupdepth, &depthsg); #endif cmd_OptionAsFlag(opts, OPT_restricted, &restricted); /* general server options */ cmd_OptionAsString(opts, OPT_auditlog, &auditFileName); if (cmd_OptionAsString(opts, OPT_auditiface, &interface) == 0) { if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); PT_EXIT(1); } free(interface); } cmd_OptionAsInt(opts, OPT_debug, &LogLevel); cmd_OptionAsString(opts, OPT_database, &pr_dbaseName); cmd_OptionAsString(opts, OPT_logfile, &logFile); if (cmd_OptionAsInt(opts, OPT_threads, &lwps) == 0) { if (lwps > 64) { /* maximum of 64 */ printf("Warning: '-p %d' is too big; using %d instead\n", lwps, 64); lwps = 64; } else if (lwps < 3) { /* minimum of 3 */ printf("Warning: '-p %d' is too small; using %d instead\n", lwps, 3); lwps = 3; } } #ifndef AFS_NT40_ENV if (cmd_OptionPresent(opts, OPT_syslog)) { serverLogSyslog = 1; cmd_OptionAsInt(opts, OPT_syslog, &serverLogSyslogFacility); } #endif /* rx options */ if (cmd_OptionPresent(opts, OPT_peer)) rx_enablePeerRPCStats(); if (cmd_OptionPresent(opts, OPT_process)) rx_enableProcessRPCStats(); cmd_OptionAsFlag(opts, OPT_rxbind, &rxBind); cmd_OptionAsInt(opts, OPT_rxmaxmtu, &rxMaxMTU); /* rxkad options */ cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck); cmd_FreeOptions(&opts); if (auditFileName) { osi_audit_file(auditFileName); osi_audit(PTS_StartEvent, 0, AUD_END); } #ifndef AFS_NT40_ENV serverLogSyslogTag = "ptserver"; #endif OpenLog(logFile); /* set up logging */ SetupLogSignals(); prdir = afsconf_Open(configDir); if (!prdir) { fprintf(stderr, "ptserver: can't open configuration directory.\n"); PT_EXIT(1); } if (afsconf_GetNoAuthFlag(prdir)) printf("ptserver: running unauthenticated\n"); #ifdef AFS_NT40_ENV /* initialize winsock */ if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); fprintf(stderr, "ptserver: couldn't initialize winsock. \n"); PT_EXIT(1); } #endif /* get this host */ gethostname(hostname, sizeof(hostname)); th = gethostbyname(hostname); if (!th) { fprintf(stderr, "ptserver: couldn't get address of this host.\n"); PT_EXIT(1); } memcpy(&myHost, th->h_addr, sizeof(afs_uint32)); /* get list of servers */ code = afsconf_GetExtendedCellInfo(prdir, NULL, "afsprot", &info, clones); if (code) { afs_com_err(whoami, code, "Couldn't get server list"); PT_EXIT(2); } /* initialize audit user check */ osi_audit_set_user_check(prdir, pr_IsLocalRealmMatch); /* initialize ubik */ ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, prdir); ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects, afsconf_CheckAuth, prdir); /* The max needed is when deleting an entry. A full CoEntry deletion * required removal from 39 entries. Each of which may refers to the entry * being deleted in one of its CoEntries. If a CoEntry is freed its * predecessor CoEntry will be modified as well. Any freed blocks also * modifies the database header. Counting the entry being deleted and its * CoEntry this adds up to as much as 1+1+39*3 = 119. If all these entries * and the header are in separate Ubik buffers then 120 buffers may be * required. */ ubik_nBuffers = 120 + /*fudge */ 40; if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) { host = SHostAddrs[0]; /* the following call is idempotent so if/when it gets called * again by the ubik init stuff, it doesn't really matter * -- klm */ rx_InitHost(host, htons(AFSCONF_PROTPORT)); } } /* Disable jumbograms */ rx_SetNoJumbo(); if (rxMaxMTU != -1) { if (rx_SetMaxMTU(rxMaxMTU) != 0) { printf("rxMaxMTU %d is invalid\n", rxMaxMTU); PT_EXIT(1); } } code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info, clones, pr_dbaseName, &dbase); if (code) { afs_com_err(whoami, code, "Ubik init failed"); PT_EXIT(2); } #if defined(SUPERGROUPS) pt_hook_write(); #endif afsconf_BuildServerSecurityObjects(prdir, &securityClasses, &numClasses); tservice = rx_NewServiceHost(host, 0, PRSRV, "Protection Server", securityClasses, numClasses, PR_ExecuteRequest); if (tservice == (struct rx_service *)0) { fprintf(stderr, "ptserver: Could not create new rx service.\n"); PT_EXIT(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, lwps); if (rxkadDisableDotCheck) { rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); } tservice = rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); if (tservice == (struct rx_service *)0) { fprintf(stderr, "ptserver: Could not create new rx service.\n"); PT_EXIT(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(pr_rxstat_userok); LogCommandLine(argc, argv, "ptserver", #if defined(SUPERGROUPS) "1.1", #else "1.0", #endif "Starting AFS", FSLog); rx_StartServer(1); osi_audit(PTS_FinishEvent, -1, AUD_END); exit(0); }
static PT_THREAD(read_temp(struct pt *pt, const ow_addr_t *addr)) { int err; uint8_t scratch[9]; uint8_t crc = 0; PT_BEGIN(pt); // Reset the bus err = ow_reset(); if (err != 1) { shell_output_P(&owtest_command, PSTR("Reset failed.\n")); PT_EXIT(pt); } // Match ROM err = ow_write_byte(0x55); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(*addr); i++) { err = ow_write_byte(addr->u[i]); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } } // Start temperature conversion err = ow_write_byte(0x44); if (err) { shell_output_P(&owtest_command, PSTR("Convert T failed\n")); PT_EXIT(pt); } // Conversion timeout timer_set(&timeout, DS18B20_CONV_TIMEOUT); while (1) { _delay_ms(10); // for good measure // Read a bit from the bus int ret = ow_read_bit(); // Check for stop conditions if (ret == 1) { break; } else if (ret == -1) { shell_output_P(&owtest_command, PSTR("Read status failed.\n")); PT_EXIT(pt); } else if (timer_expired(&timeout)) { shell_output_P(&owtest_command, PSTR("Conversion has taken too long. Giving up.\n")); PT_EXIT(pt); } // Poll the process and yield the thread process_poll(&shell_owtest_process); PT_YIELD(pt); } // Reset and MATCH ROM again err = ow_reset(); if (err != 1) { shell_output_P(&owtest_command, PSTR("Reset failed.\n")); PT_EXIT(pt); } // Match ROM err = ow_write_byte(0x55); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(*addr); i++) { err = ow_write_byte(addr->u[i]); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } } // Read the scratch pad err = ow_write_byte(0xBE); if (err) { shell_output_P(&owtest_command, PSTR("Read scratch pad failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(scratch); i++) { err = ow_read_byte(); if (err < 0) { shell_output_P(&owtest_command, PSTR("Read byte failed\n")); PT_EXIT(pt); } scratch[i] = err; crc = _crc_ibutton_update(crc, scratch[i]); } // Make sure the CRC is valid if (crc) { shell_output_P(&owtest_command, PSTR("CRC check failed!\n")); PT_EXIT(pt); } // Convert temperature to floating point int16_t rawtemp = scratch[0] | (scratch[1] << 8); float temp = (float)rawtemp * 0.0625; shell_output_P(&owtest_command, PSTR("Scratchpad: %02x%02x %02x%02x %02x %02x%02x%02x %02x\n"), scratch[0], scratch[1], // temperature scratch[2], scratch[3], // TH,TL alarm thresholds scratch[4], // config scratch[5], scratch[6], scratch[7], // reserved scratch[8]); // CRC shell_output_P(&owtest_command, PSTR("Reading: %0.2fC\n"), temp); PT_END(pt); }
int main(int argc, char **argv) { register afs_int32 code; afs_uint32 myHost; register struct hostent *th; char hostname[64]; struct rx_service *tservice; struct rx_securityClass **securityClasses; afs_int32 numClasses; int kerberosKeys; /* set if found some keys */ int lwps = 3; char clones[MAXHOSTSPERCELL]; afs_uint32 host = htonl(INADDR_ANY); const char *pr_dbaseName; char *whoami = "ptserver"; int a; char arg[100]; char *auditFileName = NULL; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGABRT, &nsa, NULL); sigaction(SIGSEGV, &nsa, NULL); #endif osi_audit_init(); osi_audit(PTS_StartEvent, 0, AUD_END); /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } pr_dbaseName = AFSDIR_SERVER_PRDB_FILEPATH; #if defined(SUPERGROUPS) /* make sure the structures for database records are the same size */ if ((sizeof(struct prentry) != ENTRYSIZE) || (sizeof(struct prentryg) != ENTRYSIZE)) { fprintf(stderr, "The structures for the database records are different" " sizes\n" "struct prentry = %" AFS_SIZET_FMT "\n" "struct prentryg = %" AFS_SIZET_FMT "\n" "ENTRYSIZE = %d\n", sizeof(struct prentry), sizeof(struct prentryg), ENTRYSIZE); PT_EXIT(1); } #endif for (a = 1; a < argc; a++) { int alen; lcstring(arg, argv[a], sizeof(arg)); alen = strlen(arg); if (strcmp(argv[a], "-d") == 0) { if ((a + 1) >= argc) { fprintf(stderr, "missing argument for -d\n"); return -1; } debuglevel = atoi(argv[++a]); LogLevel = debuglevel; } else if ((strncmp(arg, "-database", alen) == 0) || (strncmp(arg, "-db", alen) == 0)) { pr_dbaseName = argv[++a]; /* specify a database */ } else if (strncmp(arg, "-p", alen) == 0) { lwps = atoi(argv[++a]); if (lwps > 16) { /* maximum of 16 */ printf("Warning: '-p %d' is too big; using %d instead\n", lwps, 16); lwps = 16; } else if (lwps < 3) { /* minimum of 3 */ printf("Warning: '-p %d' is too small; using %d instead\n", lwps, 3); lwps = 3; } #if defined(SUPERGROUPS) } else if ((strncmp(arg, "-groupdepth", alen) == 0) || (strncmp(arg, "-depth", alen) == 0)) { depthsg = atoi(argv[++a]); /* Max search depth for supergroups */ #endif } else if (strncmp(arg, "-default_access", alen) == 0) { prp_user_default = prp_access_mask(argv[++a]); prp_group_default = prp_access_mask(argv[++a]); } else if (strncmp(arg, "-restricted", alen) == 0) { restricted = 1; } else if (strncmp(arg, "-rxbind", alen) == 0) { rxBind = 1; } else if (strncmp(arg, "-allow-dotted-principals", alen) == 0) { rxkadDisableDotCheck = 1; } else if (strncmp(arg, "-enable_peer_stats", alen) == 0) { rx_enablePeerRPCStats(); } else if (strncmp(arg, "-enable_process_stats", alen) == 0) { rx_enableProcessRPCStats(); } #ifndef AFS_NT40_ENV else if (strncmp(arg, "-syslog", alen) == 0) { /* set syslog logging flag */ serverLogSyslog = 1; } else if (strncmp(arg, "-syslog=", MIN(8, alen)) == 0) { serverLogSyslog = 1; serverLogSyslogFacility = atoi(arg + 8); } #endif else if (strncmp(arg, "-auditlog", alen) == 0) { auditFileName = argv[++a]; } else if (strncmp(arg, "-audit-interface", alen) == 0) { char *interface = argv[++a]; if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); PT_EXIT(1); } } else if (!strncmp(arg, "-rxmaxmtu", alen)) { if ((a + 1) >= argc) { fprintf(stderr, "missing argument for -rxmaxmtu\n"); PT_EXIT(1); } rxMaxMTU = atoi(argv[++a]); if ((rxMaxMTU < RX_MIN_PACKET_SIZE) || (rxMaxMTU > RX_MAX_PACKET_DATA_SIZE)) { printf("rxMaxMTU %d invalid; must be between %d-%" AFS_SIZET_FMT "\n", rxMaxMTU, RX_MIN_PACKET_SIZE, RX_MAX_PACKET_DATA_SIZE); PT_EXIT(1); } } else if (*arg == '-') { /* hack in help flag support */ #if defined(SUPERGROUPS) #ifndef AFS_NT40_ENV printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-syslog[=FACILITY]] [-d <debug level>] " "[-p <number of processes>] [-rebuild] " "[-groupdepth <depth>] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-allow-dotted-principals] " "[-enable_peer_stats] [-enable_process_stats] " "[-default_access default_user_access default_group_access] " "[-help]\n"); #else /* AFS_NT40_ENV */ printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-d <debug level>] " "[-p <number of processes>] [-rebuild] [-rxbind] " "[-allow-dotted-principals] " "[-default_access default_user_access default_group_access] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-groupdepth <depth>] " "[-help]\n"); #endif #else #ifndef AFS_NT40_ENV printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-d <debug level>] " "[-syslog[=FACILITY]] " "[-p <number of processes>] [-rebuild] " "[-enable_peer_stats] [-enable_process_stats] " "[-default_access default_user_access default_group_access] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-allow-dotted-principals] " "[-help]\n"); #else /* AFS_NT40_ENV */ printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] [-d <debug level>] " "[-default_access default_user_access default_group_access] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-allow-dotted-principals] " "[-p <number of processes>] [-rebuild] " "[-help]\n"); #endif #endif fflush(stdout); PT_EXIT(1); } #if defined(SUPERGROUPS) else { fprintf(stderr, "Unrecognized arg: '%s' ignored!\n", arg); } #endif } if (auditFileName) { osi_audit_file(auditFileName); osi_audit(PTS_StartEvent, 0, AUD_END); } #ifndef AFS_NT40_ENV serverLogSyslogTag = "ptserver"; #endif OpenLog(AFSDIR_SERVER_PTLOG_FILEPATH); /* set up logging */ SetupLogSignals(); prdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!prdir) { fprintf(stderr, "ptserver: can't open configuration directory.\n"); PT_EXIT(1); } if (afsconf_GetNoAuthFlag(prdir)) printf("ptserver: running unauthenticated\n"); #ifdef AFS_NT40_ENV /* initialize winsock */ if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); fprintf(stderr, "ptserver: couldn't initialize winsock. \n"); PT_EXIT(1); } #endif /* get this host */ gethostname(hostname, sizeof(hostname)); th = gethostbyname(hostname); if (!th) { fprintf(stderr, "ptserver: couldn't get address of this host.\n"); PT_EXIT(1); } memcpy(&myHost, th->h_addr, sizeof(afs_uint32)); /* get list of servers */ code = afsconf_GetExtendedCellInfo(prdir, NULL, "afsprot", &info, clones); if (code) { afs_com_err(whoami, code, "Couldn't get server list"); PT_EXIT(2); } pr_realmName = info.name; { afs_int32 kvno; /* see if there is a KeyFile here */ struct ktc_encryptionKey key; code = afsconf_GetLatestKey(prdir, &kvno, &key); kerberosKeys = (code == 0); if (!kerberosKeys) printf ("ptserver: can't find any Kerberos keys, code = %d, ignoring\n", code); } if (kerberosKeys) { /* initialize ubik */ ubik_CRXSecurityProc = afsconf_ClientAuth; ubik_CRXSecurityRock = prdir; ubik_SRXSecurityProc = afsconf_ServerAuth; ubik_SRXSecurityRock = prdir; ubik_CheckRXSecurityProc = afsconf_CheckAuth; ubik_CheckRXSecurityRock = prdir; } /* The max needed is when deleting an entry. A full CoEntry deletion * required removal from 39 entries. Each of which may refers to the entry * being deleted in one of its CoEntries. If a CoEntry is freed its * predecessor CoEntry will be modified as well. Any freed blocks also * modifies the database header. Counting the entry being deleted and its * CoEntry this adds up to as much as 1+1+39*3 = 119. If all these entries * and the header are in separate Ubik buffers then 120 buffers may be * required. */ ubik_nBuffers = 120 + /*fudge */ 40; if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = parseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) { host = SHostAddrs[0]; /* the following call is idempotent so if/when it gets called * again by the ubik init stuff, it doesn't really matter * -- klm */ rx_InitHost(host, htons(AFSCONF_PROTPORT)); } } code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info, clones, pr_dbaseName, &dbase); if (code) { afs_com_err(whoami, code, "Ubik init failed"); PT_EXIT(2); } #if defined(SUPERGROUPS) pt_hook_write(); #endif afsconf_BuildServerSecurityObjects(prdir, 0, &securityClasses, &numClasses); /* Disable jumbograms */ rx_SetNoJumbo(); if (rxMaxMTU != -1) { rx_SetMaxMTU(rxMaxMTU); } tservice = rx_NewServiceHost(host, 0, PRSRV, "Protection Server", securityClasses, numClasses, PR_ExecuteRequest); if (tservice == (struct rx_service *)0) { fprintf(stderr, "ptserver: Could not create new rx service.\n"); PT_EXIT(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, lwps); if (rxkadDisableDotCheck) { rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); } tservice = rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); if (tservice == (struct rx_service *)0) { fprintf(stderr, "ptserver: Could not create new rx service.\n"); PT_EXIT(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(pr_rxstat_userok); LogCommandLine(argc, argv, "ptserver", #if defined(SUPERGROUPS) "1.1", #else "1.0", #endif "Starting AFS", FSLog); rx_StartServer(1); osi_audit(PTS_FinishEvent, -1, AUD_END); exit(0); }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_udpthread(struct pt *pt)) { int len; struct codeprop_udphdr *uh = (struct codeprop_udphdr *)uip_appdata; /* if(uip_newdata()) { PRINTF(("recv_udpthread: id %d uh->id %d\n", s.id, htons(uh->id))); }*/ PT_BEGIN(pt); while(1) { do { PT_WAIT_UNTIL(pt, uip_newdata() && uh->type == HTONS(TYPE_DATA) && htons(uh->id) > s.id); if(htons(uh->addr) != 0) { s.addr = 0; send_nack(uh, 0); } } while(htons(uh->addr) != 0); /* leds_on(LEDS_YELLOW); beep_down(10000);*/ s.addr = 0; s.id = htons(uh->id); s.len = htons(uh->len); timer_set(&s.timer, CONNECTION_TIMEOUT); /* process_post(PROCESS_BROADCAST, codeprop_event_quit, (process_data_t)NULL); */ while(s.addr < s.len) { if(htons(uh->addr) == s.addr) { /* leds_blink();*/ len = uip_datalen() - UDPHEADERSIZE; if(len > 0) { /* eeprom_write(EEPROMFS_ADDR_CODEPROP + s.addr, &uh->data[0], len);*/ cfs_seek(fd, s.addr, CFS_SEEK_SET); cfs_write(fd, &uh->data[0], len); /* beep();*/ PRINTF(("Saved %d bytes at address %d, %d bytes left\n", uip_datalen() - UDPHEADERSIZE, s.addr, s.len - s.addr)); s.addr += len; } } else if(htons(uh->addr) > s.addr) { PRINTF(("sending nack since 0x%x != 0x%x\n", htons(uh->addr), s.addr)); send_nack(uh, s.addr); } if(s.addr < s.len) { /* timer_set(&s.nacktimer, NACK_TIMEOUT);*/ do { timer_set(&s.nacktimer, HIT_NACK_TIMEOUT); PT_YIELD_UNTIL(pt, timer_expired(&s.nacktimer) || (uip_newdata() && uh->type == HTONS(TYPE_DATA) && htons(uh->id) == s.id)); if(timer_expired(&s.nacktimer)) { send_nack(uh, s.addr); } } while(timer_expired(&s.nacktimer)); } } /* leds_off(LEDS_YELLOW); beep_quick(2);*/ /* printf("Received entire bunary over udr\n");*/ codeprop_start_program(); PT_EXIT(pt); } PT_END(pt); }
static PT_THREAD( LOG_log(pt_t* pt) ) { u32 time; u8 is_filtered; u8 i; PT_BEGIN(pt); // systematically unlock the channel // because most of time no response is sent // when a response is needed, the channel will be locked DPT_unlock(&LOG.interf); switch ( LOG.state ) { case LOG_OFF: default: // empty the log fifo (void)FIFO_get(&LOG.in_fifo, &LOG.fr); // loop back for next frame PT_RESTART(pt); break; case LOG_RAM: #ifdef SAVE_IN_RAM_ENABLED #endif break; case LOG_EEPROM: // if address is out of range if ( LOG.eeprom_addr >= EEPROM_END_ADDR ) { // logging is no more possible // so quit PT_EXIT(pt); } break; case LOG_SDCARD: // if address is out of range if ( LOG.sdcard_addr >= SDCARD_END_ADDR ) { // logging is no more possible // so quit PT_EXIT(pt); } break; } // wait while no frame is present in the fifo PT_WAIT_WHILE(pt, KO == FIFO_get(&LOG.in_fifo, &LOG.fr)); // if it is a log command if ( (LOG.fr.cmde == FR_LOG_CMD) && (!LOG.fr.resp) ) { // treat it LOG_command(&LOG.fr); // send the response DPT_lock(&LOG.interf); PT_WAIT_UNTIL(pt, OK == DPT_tx(&LOG.interf, &LOG.fr)); DPT_unlock(&LOG.interf); // and wait till the next frame PT_RESTART(pt); } // filter the frame according to its origin is_filtered = OK; // by default, every frame is filtered for ( i = 0; i < sizeof(LOG.orig_filter); i++ ) { // passthrough or frame origin and filter acceptance match if ( (LOG.orig_filter[i] == 0x00) || (LOG.orig_filter[i] == LOG.fr.orig) ){ is_filtered = KO; break; } } // if frame is filtered away if ( is_filtered ) { // lop back for next frame PT_RESTART(pt); } // build the log packet LOG.block.index = LOG.index; time = TIME_get(); LOG.block.time[0] = (u8)(time >> 16); LOG.block.time[1] = (u8)(time >> 8); LOG.block.fr = LOG.fr; switch ( LOG.state ) { case LOG_OFF: default: // shall never happen but just in case // loop back for next frame PT_RESTART(pt); break; case LOG_RAM: #ifdef SAVE_IN_RAM_ENABLED LOG.ram_buffer[LOG.ram_index] = LOG.block; if ( LOG.ram_index < (RAM_BUFFER_SIZE - 1) ) { LOG.ram_index++; } #endif break; case LOG_EEPROM: // save it to eeprom PT_WAIT_UNTIL(pt, EEP_write(LOG.eeprom_addr, (u8*)&LOG.block, sizeof(log_t))); // wait until saving is done PT_WAIT_UNTIL(pt, EEP_is_fini()); break; case LOG_SDCARD: // save it to sdcard (fill the write buffer) PT_WAIT_UNTIL(pt, SD_write(LOG.sdcard_addr, (u8*)&LOG.block, sizeof(log_t))); // wait until saving is done break; } // loop back to treat the next frame to log PT_RESTART(pt); PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(publish_pt(struct pt *pt, struct mqtt_connection *conn)) { PT_BEGIN(pt); DBG("MQTT - Sending publish message! topic %s topic_length %i\n", conn->out_packet.topic, conn->out_packet.topic_length); DBG("MQTT - Buffer space is %i \n", &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_PUBLISH | conn->out_packet.qos << 1; if(conn->out_packet.retain == MQTT_RETAIN_ON) { conn->out_packet.fhdr |= MQTT_FHDR_RETAIN_FLAG; } conn->out_packet.remaining_length = MQTT_STRING_LEN_SIZE + conn->out_packet.topic_length + conn->out_packet.payload_size; if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) { conn->out_packet.remaining_length += MQTT_MID_SIZE; } encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); PRINTF("MQTT - Error, remaining length > 4 bytes\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); /* Write Variable Header */ PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic, conn->out_packet.topic_length); if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) { PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); } /* Write Payload */ PT_MQTT_WRITE_BYTES(conn, conn->out_packet.payload, conn->out_packet.payload_size); send_out_buffer(conn); timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); /* * If QoS is zero then wait until the message has been sent, since there is * no ACK to wait for. * * Also notify the app will not be notified via PUBACK or PUBCOMP */ if(conn->out_packet.qos == 0) { process_post(conn->app_process, mqtt_update_event, NULL); } else if(conn->out_packet.qos == 1) { /* Wait for PUBACK */ reset_packet(&conn->in_packet); PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || timer_expired(&conn->t)); if(timer_expired(&conn->t)) { DBG("Timeout waiting for PUBACK\n"); } if(conn->in_packet.mid != conn->out_packet.mid) { DBG("MQTT - Warning, got PUBACK with none matching MID. Currently there " "is no support for several concurrent PUBLISH messages.\n"); } } else if(conn->out_packet.qos == 2) { DBG("MQTT - QoS not implemented yet.\n"); /* Should wait for PUBREC, send PUBREL and then wait for PUBCOMP */ } reset_packet(&conn->in_packet); /* This is clear after the entire transaction is complete */ conn->out_queue_full = 0; DBG("MQTT - Publish Enqueued\n"); PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(unsubscribe_pt(struct pt *pt, struct mqtt_connection *conn)) { PT_BEGIN(pt); DBG("MQTT - Sending unsubscribe message on topic %s topic_length %i\n", conn->out_packet.topic, conn->out_packet.topic_length); DBG("MQTT - Buffer space is %i \n", &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_UNSUBSCRIBE | MQTT_FHDR_QOS_LEVEL_1; conn->out_packet.remaining_length = MQTT_MID_SIZE + MQTT_STRING_LEN_SIZE + conn->out_packet.topic_length; encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); PRINTF("MQTT - Error, remaining length > 4 bytes\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); /* Write Variable Header */ PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF)); /* Write Payload */ PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF)); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic, conn->out_packet.topic_length); /* Send out buffer */ send_out_buffer(conn); timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); /* Wait for UNSUBACK */ reset_packet(&conn->in_packet); PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || timer_expired(&conn->t)); if(timer_expired(&conn->t)) { DBG("Timeout waiting for UNSUBACK\n"); } reset_packet(&conn->in_packet); /* This is clear after the entire transaction is complete */ conn->out_queue_full = 0; DBG("MQTT - Done writing subscribe message to out buffer!\n"); PT_END(pt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(connect_pt(struct pt *pt, struct mqtt_connection *conn)) { PT_BEGIN(pt); DBG("MQTT - Sending CONNECT message...\n"); /* Set up FHDR */ conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_CONNECT; conn->out_packet.remaining_length = 0; conn->out_packet.remaining_length += MQTT_CONNECT_VHDR_FLAGS_SIZE; conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->client_id); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.username); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.password); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.topic); conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.message); encode_remaining_length(conn->out_packet.remaining_length_enc, &conn->out_packet.remaining_length_enc_bytes, conn->out_packet.remaining_length); if(conn->out_packet.remaining_length_enc_bytes > 4) { call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL); PRINTF("MQTT - Error, remaining length > 4 bytes\n"); PT_EXIT(pt); } /* Write Fixed Header */ PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr); PT_MQTT_WRITE_BYTES(conn, conn->out_packet.remaining_length_enc, conn->out_packet.remaining_length_enc_bytes); PT_MQTT_WRITE_BYTE(conn, 0); PT_MQTT_WRITE_BYTE(conn, 6); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)MQTT_PROTOCOL_NAME, 6); PT_MQTT_WRITE_BYTE(conn, MQTT_PROTOCOL_VERSION); PT_MQTT_WRITE_BYTE(conn, conn->connect_vhdr_flags); PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive >> 8)); PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive & 0x00FF)); PT_MQTT_WRITE_BYTE(conn, conn->client_id.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->client_id.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->client_id.string, conn->client_id.length); if(conn->connect_vhdr_flags & MQTT_VHDR_WILL_FLAG) { PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->will.topic.string, conn->will.topic.length); PT_MQTT_WRITE_BYTE(conn, conn->will.message.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->will.message.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->will.message.string, conn->will.message.length); DBG("MQTT - Setting will topic to '%s' %u bytes and message to '%s' %u bytes\n", conn->will.topic.string, conn->will.topic.length, conn->will.message.string, conn->will.message.length); } if(conn->connect_vhdr_flags & MQTT_VHDR_USERNAME_FLAG) { PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->credentials.username.string, conn->credentials.username.length); } if(conn->connect_vhdr_flags & MQTT_VHDR_PASSWORD_FLAG) { PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length << 8); PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length & 0x00FF); PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->credentials.password.string, conn->credentials.password.length); } /* Send out buffer */ send_out_buffer(conn); conn->state = MQTT_CONN_STATE_CONNECTING_TO_BROKER; timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT); /* Wait for CONNACK */ reset_packet(&conn->in_packet); PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK || timer_expired(&conn->t)); if(timer_expired(&conn->t)) { DBG("Timeout waiting for CONNACK\n"); /* We stick to the letter of the spec here: Tear the connection down */ mqtt_disconnect(conn); } reset_packet(&conn->in_packet); DBG("MQTT - Done sending CONNECT\n"); #if DEBUG_MQTT == 1 DBG("MQTT - CONNECT message sent: \n"); uint16_t i; for(i = 0; i < (conn->out_buffer_ptr - conn->out_buffer); i++) { DBG("%02X ", conn->out_buffer[i]); } DBG("\n"); #endif PT_END(pt); }